一、通用寄存器
AX、BX、CX和DX是四个通用寄存器,通常用来存放一般性的数据,后面的分析都在8086CPU中进行。每个通用寄存器是16位,即一次可以处理一个字(2个字节)的数据,但是为了与8086CPU之前的CPU相容,也支持一个字节的寄存器,即AH与AL,类似的还有BH和BL等,CPU操作时会降AH和AL当作独立的寄存器,运算进位时会直接丢弃,因为CPU认为只有一个8位的寄存器而已:
我们是否可以修改控制CS:IP的值呢?答案是肯定的,只不过我们不能使用mov等传送指令,而应当使用jmp这类转移指令,基本的用法是:
-1. 修改CS:IP: jmp 2AE3:3 执行后:CS=2AE3H, IP=0003H;
-2. 仅修改IP:jmp ax(ie. move ip, ax)即用寄存器中的值修改IP;
三、内存访问
CPU访问内存除了获取指令,还要获取数据,那么数据部分如何定位的呢?同指令的CS:IP一样,8086CPU使用DS:[...]来获取内存数据地址,其中段寄存器存储内存数据段的基地址,而[...]表示一个内存偏移量指向的内存单元,如[0]表示偏移量为0的内存单元,这里使用时要注意,8086CPU不支持直接对DS传送值,因此mov ds, 1000H是非法的,正确地是通过寄存器来实现,即:mov ax, 1000H; mov ds, ax;
这部分我们要学习基本的汇编指令,如mov、sub、add等,都可以操作寄存器,操作完之后将数据放入第一个参数表示的寄存器中。CPU中的内存数据一种特殊的结果就是栈,即只能从一端读写数据的结构,其基本指令是push ax;将寄存器ax的值入栈;和pop ax;从栈中取出栈顶元素放入寄存器ax中;下面是mov\add\sub命令的一个简单示例:
我们是否可以修改控制CS:IP的值呢?答案是肯定的,只不过我们不能使用mov等传送指令,而应当使用jmp这类转移指令,基本的用法是:
-1. 修改CS:IP: jmp 2AE3:3 执行后:CS=2AE3H, IP=0003H;
-2. 仅修改IP:jmp ax(ie. move ip, ax)即用寄存器中的值修改IP;
三、内存访问
CPU访问内存除了获取指令,还要获取数据,那么数据部分如何定位的呢?同指令的CS:IP一样,8086CPU使用DS:[...]来获取内存数据地址,其中段寄存器存储内存数据段的基地址,而[...]表示一个内存偏移量指向的内存单元,如[0]表示偏移量为0的内存单元,这里使用时要注意,8086CPU不支持直接对DS传送值,因此mov ds, 1000H是非法的,正确地是通过寄存器来实现,即:mov ax, 1000H; mov ds, ax;
这部分我们要学习基本的汇编指令,如mov、sub、add等,都可以操作寄存器,操作完之后将数据放入第一个参数表示的寄存器中。CPU中的内存数据一种特殊的结果就是栈,即只能从一端读写数据的结构,其基本指令是push ax;将寄存器ax的值入栈;和pop ax;从栈中取出栈顶元素放入寄存器ax中;下面是mov\add\sub命令的一个简单示例:
然后我们来看看PUSH命令的执行过程:
然后是POP命令:
可以看出,栈的操作关键是栈顶位置的确定,因此CPU专门使用SS:SP来获取当前内存中栈顶的位置。值得一提的是,CPU本身并没有对栈的大小进行检查,因此实际中会出现栈顶越界的问题(上限超出-PUSH;下限超出-POP),这也就要求我们必须人为进行检查,否则就会出现程序的漏洞。