汇编初学(第一部分:内存操作)

——《汇编语言第三版》 王爽


[toc]

一. 问题提出

  1. 存储在内存中的都是二进制数,如何区分指令,数据和栈空间?

二. 基础知识

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的工作过程可以描述如下:
  1. 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲区;
  2. IP=IP+所读取的指令的长度,从而指向下一条指令;
  3. 执行指令。转到步骤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

上述指令执行了以下几个操作

  1. 将1000H放入AX寄存器
  2. 将栈段地址寄存器赋值1000H
  3. 将栈偏移地址寄存器赋值0010H
  4. 将AX寄存器的值压入栈
  5. 将BX寄存器的值压入栈
  6. 将DS寄存器的值压入栈

3.3 注意事项

  1. 在汇编操作的过程中,8086CPU并不支持直接将值赋予SS寄存器,但是可以直接将值赋予SP寄存器
  2. 在入栈时,地址是从高向低增长。

三. 思考

  1. 内存里是二进制数,并不具备所谓的数据、命令、栈空间的区别,全都是一个个的二进制数;
  2. 当CS、IP指向的是命令,DS、[Adress]指向的是数据,SS、SP指向栈空间的栈顶数据。

你可能感兴趣的:(汇编初学(第一部分:内存操作))