——《汇编语言第三版》 王爽
[toc]
一. 问题提出
- 存储在内存中的都是二进制数,如何区分指令,数据和栈空间?
二. 基础知识
1. CS 和 IP
1.1 定义
CS是代码段寄存器,IP是指令指针寄存器。
1.2 用法
如果需要到20003H处寻找指令,即CS:IP = 2000:0003。
可以
jmp 2000:3,
此句执行后,CS = 2000H,IP=0003H,CPU将从20003H处读取指令。
物理地址:20003H = 2000H(段地址) × 16 + 0003H(偏移地址)。(此处之所以×16是因为在8086CPU合成地址的规定,并不具备普遍意义。)
只要符合“段地址×规定倍率 + 偏移地址”格式得到的最终物理地址均有效,允许出现段地址与偏移地址不相同但是最终物理地址相同的情况。
1.3 注意事项
- 8086CPU的工作过程可以描述如下:
- 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲区;
- IP=IP+所读取的指令的长度,从而指向下一条指令;
- 执行指令。转到步骤1,重复这个过程。
- 在8086CPU中,无法直接对CS及IP寄存器进行操作,而通过“jmp 段地址:偏移地址”的指令进行对CS和IP寄存器的修改。
2. DS 和 [Adress]
2.1 定义
CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086中,内存地址有段地址和偏移地址组成。
上段所说的指向数据内存的段地址寄存器为DS。
2.2 用法
假如我们需要访问10000H单元的内容,可以用如下的程序段进行:
mov bx,1000H
mov ds,bx
mov al,[0]
上述的3条指令将10000H(1000:0)中的数据读到al。
2.3 注意事项
完成上述指令目标时,为什么不能用下面的指令实现?
mov ds,1000H
即思考为什么不能将数值直接送入DS寄存器?
关于这一点,这是因为8086的CPU硬件设计部分的原因,感兴趣可以自己进行寻找答案。
3. SS 和 SP
3.1 定义
8086CPU用SS和SP指示栈顶的位置,SS为段地址,SP为偏移地址。常与push和pop指令连在一起用。
在这使用的过程中,假如我们定义的栈空间为指定大小x,栈空间的其实地址为a。
那么可能出现栈满时执行push或着栈空的时候执行pop带来的“栈顶超界”问题,8086并没有提供有关记录栈顶空间的寄存器,需要编程者自己注意。
3.2 用法
mov ax,1000H
mov ss,ax
mov sp,0010H
push ax
push bx
push ds
上述指令执行了以下几个操作
- 将1000H放入AX寄存器
- 将栈段地址寄存器赋值1000H
- 将栈偏移地址寄存器赋值0010H
- 将AX寄存器的值压入栈
- 将BX寄存器的值压入栈
- 将DS寄存器的值压入栈
3.3 注意事项
- 在汇编操作的过程中,8086CPU并不支持直接将值赋予SS寄存器,但是可以直接将值赋予SP寄存器。
- 在入栈时,地址是从高向低增长。
三. 思考
- 内存里是二进制数,并不具备所谓的数据、命令、栈空间的区别,全都是一个个的二进制数;
- 当CS、IP指向的是命令,DS、[Adress]指向的是数据,SS、SP指向栈空间的栈顶数据。
网友评论