内存中字的存储
基础知识
内存中,一个字要用两个地址连续的内存单元存放,这个字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。例如,用0,1两个内存单元存放数据20000(4E20H),对于这个字单元来说,0号单元是低地址单元,1号单元是高地址单元,则字型数据低位字节(20)存放在0号单元中,高位字节(4E)存放在1号单元中
在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器,低地址单元和低8位寄存器相对应
DS 和 [address]
mov 指令可以完成以下几种数据传送
- 数据直接送入寄存器
- 将一个寄存器中的内容送入另一个寄存器
- 将一个内存单元中的内容送入一个寄存器中
mov bx,1000H
mov ds,bx
mov al,[0] 完成数据从1000:0单元到al的传送
注意:8086CPU并不支持直接将数据送入 段寄存器 的操作,因此需要一个寄存器(ax)中转
栈(stack)
CPU提供的栈机制
基本命令
- push ax 将寄存器ax中的数据送入栈中
- pop ax 从栈顶取出数据送入ax
8086CPU这两个操作都是以字为单位进行的,字型数据用两个单元存放,高地址单元存放高8位,低地址单元存放低8位
栈空间是从高地址向低地址增长,先入栈的数据物理地址高
任意时刻,SS:SP 指向栈顶元素 push和pop指令执行时,CPU从SS和SP中得到栈顶的地址
push操作:
- SP = SP-2, SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶
- 将ax中内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶
ps:如果将10000H~1000FH这段空间当作栈,初始状态栈是空的,此时 SS=1000H, 则SP= 0010H
pop操作:
- 将SS:SP指向的内存单元处数据送入ax中
- SP = SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶
push 和 pop指令
有以下几种形式
- push 寄存器
- push 段寄存器
- push 内存单元
注 push 和 pop 指令可能发生栈顶越界问题,8086CPU只记录栈顶,栈空间大小要我们自己管理
数据处理
数据处理有两个基本问题
- 处理的数据在什么地方
- 要处理的数据有多长
这两个问题在机器指令中必须明确或隐含地说明 (以下用reg表示一个寄存器,sreg表示一个段寄存器)
基础总结
- 8086CPU,只有四个寄存器:bx,si,di,bp 可以用在[….]中进行内存单元的寻址
如 mov ax,[bx] mov ax,[bx+si] mov ax,[bx+di] mov ax,[bp]
- [….]中,这4个寄存器可以单个出现,或 只能以4中组合出现 ,bx和si,bx和di,bp和si,bp和di
- 只要在[…]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中
指令要处理的数据有多长
8086CPU指令可以处理两种尺寸的数据,byte 和 word。所以在机器指令中要指明,指令进行的是字操作还是字节操作。可以用以下方法处理
- 通过寄存器名指明要处理的数据的尺寸
mov ax,1
mov bx,ds:[0] ;寄存器指明了指令进行的是字操作
mov al,1
mov al,bl
mov al,ds:[0] ;寄存器指明了指令进行的是字节操作
- 在没有寄存器名存在的情况下,用操作符X ptr 指明内存单元的长度,X在汇编指令中可以为word 和 byte
mov word ptr ds:[0],1
inc word ptr [bx]
mov byte ptr ds:[0],1
inc byte ptr [bx]
注:在没有寄存器参与的内存单元访问指令中,用word ptr 或 byte ptr 显性指明所要访问的内存单元的长度是很有必要的。否则CPU无法得知所要访问的单元是字单元还是字节单元。
- 其他方法—-有些指令默认了访问的是字节单元还是字单元,比如push [1000h] 就不用指明访问的是字节还是字单元,因为push指令只进行字操作