内存中字的存储

基础知识

内存中,一个字要用两个地址连续的内存单元存放,这个字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。例如,用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表示一个段寄存器)

基础总结

  1. 8086CPU,只有四个寄存器:bx,si,di,bp 可以用在[….]中进行内存单元的寻址

如 mov ax,[bx] mov ax,[bx+si] mov ax,[bx+di] mov ax,[bp]

  1. [….]中,这4个寄存器可以单个出现,或 只能以4中组合出现 ,bx和si,bx和di,bp和si,bp和di
  2. 只要在[…]中使用寄存器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指令只进行字操作