0%

寄存器(内存访问)

内存中字的存储

字单元 : 即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元存放字型数据的高位字节,低地址内存单元存放字型数据的低位字节。

任何两个地址连续的内存单元,N 号单元和N+1 号单元,可以将它们看成两个内存单元,也可看成一个地址为N的字单元中的高位字节单元和低位字节单元。

DS和[address]

8086 CPU有一个DS寄存器,通常用来存放要访问的数据的段地址:

1
2
3
mov bx,1000H
mov ds,bx
mov al,[0]

“[…]”表示一个内存单元,“[…]”中的0表示内存单元的偏移地址。段地址存在DS寄存器中。8086 CPU不支持将数据直接送入段寄存器,故需要用一个寄存器进行中转。

8086 CPU一次性传送16位的数据,即一个字。

mov、add、sub指令

1
2
3
4
5
6
7
mov 寄存器,数据
mov 寄存器,寄存器
mov 寄存器,内存单元
mov 寄存器,段寄存器
mov 内存单元,寄存器
mov 段寄存器,寄存器
mov 段寄存器,内存单元
1
2
3
4
add 寄存器,数据
add 寄存器,寄存器
add 寄存器,内存单元
add 内存单元,寄存器

将add换成sub也一样

1
2
3
4
5
6
7
8
9
mov ax,0123H
push ax
mov bx,2266H
push bx
mov cx,1122H
push cx
pop ax
pop bx
pop cx

执行过程如下图:
执行过程

CPU通过CS IP知道当前要执行的指令所在的地址,但是如何知道栈顶的位置呢?
在8086CPU中,有两个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素。

push ax 的执行,有以下两步完成:

  • SP = SP - 2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶。
  • 将ax中的内容送到 SS:SP 指向的内存单元处,SS:SP 此时指向栈顶。

push指令执行过程
从图中可以看出,8086CPU中,入栈时,栈顶从高地址向地址方向增长。

当栈为空时,栈中没有元素,也就不存在栈顶元素。所以SS:SP只能指向栈的最底部单元下面的单元。如果栈底部单元地址为1000:000E,则栈空时,SS:SP = 1000:0010H

pop指令执行过程
pop指令执行过程

8086 CPU没有记录栈顶元素上限和栈底的寄存器,这要程序员自己注意。

pop、push指令

1
2
3
push 寄存器
push 段寄存器
push 内存单元

pop也一样。

栈段

一段内存,可以即使代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么都不是。关键在于CPU中寄存器的设置,即CS IP SS SP DS的指向。

对于数据段,将它的段地址放在DS中,用mov、add、sub等访问内存单元的指令时,CPU就将我们定义的数据段的内容当做数据来访问。

对于代码段,将它的段地址放在CS中,将段的第一条指令地址放在IP中,这样CPU就会执行我们定义的代码段中的指令。

对于栈段,将它的段地址放在SS中,将栈顶单元的偏移地址放在SP中。

汇编指令编程

(1)关于D命令
-d 1000:0000 : 执行时段地址1000存放在DS中。

1
2
-d cs:0     //查看当前代码段中的指令代码
-d ss:0 //查看当前栈段中的内容

E A U也可以带内存单元地址

1
2
3
4
-r ds
-e ds:0 11 22 33 44 55 66
-u cs:0
-a ds:0