字
一个字占用两个字节。
任何两个地址连续的内存单元,n号单元和n+1号单元,可以将它们看成两个内存单元,也可以将它们看成一个地址为n的字单元中的高位字节单元和低位字节单元。
DS寄存器和[address]偏移地址
cpu要读取一个内存单元时,必须先给出这个内存单元的地址。DS寄存器通常用来存放要访问的数据的段地址。
如果要读取10000H单元的内容可以用如下程序段进行:
mov bx,1000H
mov ds,bx
mov al,[0]
mov指令除了可以将数据直接送入寄存器、将一个寄存器的内容送入另外一个寄存器外,还有另外一个功能,就是可以将一个内存单元中的内容送入一个寄存器。
上面代码mov al,[0]
是将偏移地址为0的内存中的数据送入al,运行指令时8086cpu会自动获取DS中的数据为内存单元的段地址。
上面代码分了两步把1000H放入ds寄存器中,因为8086cpu不支持将数据直接送入段寄存器。
字型数据的传送
8086cpu是16位结构,有16根数据线,可以一次性传送16位的数据,也就是一个字。
mov bx,1999H
mov ds,bx
mov ax,[0] ;1999:0处的字型数据送入ax
mov [0],cx ;cx中的16位数据送到1999:0处
mov、add、sub指令
mov 寄存器,数据
mov 寄存器,寄存器
mov 寄存器,内存单元
mov 内存单元,寄存器
mov 段寄存器,寄存器
mov 寄存器,段寄存器
数据段
8086机中,可以根据需要将一组内存单元定义为一个段(代码段、数据段等)。段的长度为n(n<=64k)、地址连续、起始地址为16的倍数。
访问数据段中的数据时,用ds存放数据段的段地址,再根据需要,用相关指令访问段中的具体单元。
栈
栈是一种具有特殊的访问方式的存储空间,先进后出,后进先出。
栈有两个基本的操作:
- 入栈:将一个新的元素放到栈顶。
- 出栈:从栈顶取出一个元素。
8086cpu提供相关的指令来以栈的方式访问内存空间,入栈指令为push
,出栈指令为pop
。
- push ax:将寄存器ax中的数据送入栈中。
- pop ax:从栈顶取出数据送入ax。
- push ds
- pop [0]
- 8086cpu的入栈和出栈操作都是以字为单位进行的。
8086cpu中有两个寄存器:
- 段寄存器SS:存放栈顶的段地址。
- 寄存器sp:存放栈顶的偏移地址。
- 任意时刻,SS:SP指向栈顶元素。
执行push ax
时cpu会进行如下操作
- SP = SP - 2;
- 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶;
执行pop ax
时会进行如下操作
- 从SS:SP指向的字单元中读取数据送入ax中;
- SP = SP + 2;
栈顶超界问题(溢出)
当栈满的时候使用push指令入栈,栈空的时候使用pop指令出栈,都将发生栈顶超界问题。栈空间之外可能存放一些其他用途的数据、代码等,所以栈顶超界是危险的。
8086CPU只记录栈顶,栈空间大小我们要自己管理。
push、pop等栈操作指令,修改的只是SP。所以栈顶的变化范围最大为:0~FFFFH。
栈段
将长度为n(n<=64k)的一组连续、起始地址为16倍数的内存单元,当作栈来用,就定义了一个栈段。
将SS:SP指向我们定义的栈段,即可访问我们定义的栈段。
如果将10000H~1FFFFH这段空间当作栈段,初始状态为空,那么此时SS=1000H,SP=0。