jmp命令用来简单的转移,可以写jmp 2000:1000,或者单独写jmp 1000,后者表示单独调整ip
这样的话,要用a命令写汇编的时候,要写 a 2000:1000 要指明,不然用t没法执行。。
debug命令挺好玩的。
r是用来显示寄存器。
d是用来列出内存中的内容,用“d 段地址:偏移地址”可以查8*16个内存单元。再使用d就可以查后续。
也可以指定最大偏移,使用“d 段地址:最小偏移地址 最大偏移地址”这样可以查一个指定范围,当然最大最小如果相同,就是指定查找1个。
e命令式用来改写内存中的内容的,可以用“e 起始地址 数据 数据 数据…”来改写起始地址以及之后的地址的值。
也可以用另一种提示的方法修改:比如输入e 0b2d:30a 这是光标会停在”.”后面,前面是该内存单元的值,可以输入想要的值。继续修改下一个就按space,修改完成就按enter。
t是用来执行用的,记得执行之前要用 r cs 和r ip 来指定要执行的内存地址
a 是用来写汇编语句的,当然要写之前,先要执行“a 段地址:偏移地址”这样才能写特定的地址段
在ffff:0 f这个地址段是存有主板bios的日期,当然,这个是rom,改写不了的。
4个通用寄存器,AX BX CX 和DX
段寄存器:CS DS SS ES
CS 代码段寄存器 (记录代码执行的段地址)
DS 用来存放要访问数据的段地址
IP 指令指针寄存器(记录偏移地址)
我们往通用寄存器里写数据是很容易的,比如就是写mov ax,1000H
但是要读写一个内存单元的数据呢,我们要如何写呢?
这时候就要用到一个DS,作为中介,存下需要访问的段地址
具体使用方法:
段寄存器不能用数据来直接赋值,mov ds,1000H是不能够的,这是Intel的CPU禁止的。
但是我们可以用通用寄存器给段寄存器赋值。。这又是用通用寄存器来做中介。。2次中介。。
比如说,我们要读写10000H(这是实际地址,段地址是该地址/16)这个地址上的数据
我们这样写:
mov ax,1000H
mov ds,ax
mov ax,[0]
其实[0]是[0000]的简写,是偏移地址值,使用[],cpu会自动调用ds
这样ax里,al保存的是地址10000H的值,ah保存的是地址10001H里的值。
如果我们要写地址,那么我们要给地址单位赋值:
地址单位也必须是通过寄存器来中转复制的,可以使通用的,也可以是段的
mov [0],ax
这样10000H保存的是al,10001H保存的是ah。
这是因为8086CPU的位数关系,一次是16位,在内存中表现为一个字单位,2个字节。。
可以给[]赋值,它接受寄存器,段寄存器为值,这样改写的是内存单元
给ds赋值,它接受寄存器,内存单元为值,这个就比较奇妙了:
把[0]赋值给ds,这还好,如果把[1]赋值给ds,这样ds就改了,[0],[1]就更新了,呵呵
那如果我这么做,可操作的内存地址是不是可以存在某个地方,然后统一调用?
栈,是由ss段寄存器和sp偏移寄存器里指向栈顶元素的。存入和取出栈内的字,sp都会-2或者+2
以10000H为例,我们要做一个10000H~1FFFFH的栈,那么,SS要设为1000H,sp要设为0.
为什么是0呢,因为如果栈里有一个字的话,sp指向的是这个元素低位,一个字占据1FFFF和1FFFE的位置,sp指向FFFE。
那么当栈为空的话,sp+2,就为0了。
那如果栈是满的情况呢?当然,还是0了。如果还要继续压栈,就循环覆盖了。
我们设栈的时候设定为16的倍数,以F结尾,最大是0~FFFF也就是64K。
当然,压入栈中的,是寄存器,也可以是内存单元。
其实就是对内存的一种人为分段,就像写代码时候一段一段的。不过这种分段的制度很重要。话说编程最喜欢的也就是分段了。。要切成一小块一小块的。
debug的D命令后面跟的地址,应该是放到ds寄存器中的。
debug的T命令在执行修改SS的操作时,下一条指令会跟着执行
