内存到寄存器的储存

寄存器是16位的,可以存放一个字即两个字节,而内存中的一个存储单元是一字节。所以一个寄存器可以存两个存储单元的内容,高地址存储单元存在高位字节中,低地址存储单元存在低位字节中。

字单元:存放一个字型数据的两个地址连续的内存单元。

DS寄存器

与CS类似,DS寄存器存放的是要从内存中读取的数据的段地址。我们想要使用mov指令从内存10000H(1000:0)中的数据送给AL时,如下:

mov al,[0]

后面的[0]指的是内存的偏移地址是0,CPU会自动从DS寄存器中提取段地址,所以应该首先将段地址1000H写入DS寄存器中。但却不能直接使用mov ds,1000指令,只能从其他寄存器中转传入DS寄存器。所以完整命令如下:

  1. mov bx,1000h
  2. mov ds,bx
  3. mov al,[0] ;把10000(1000:0)中的数据读到al中,对于内存寻址的语法是用`[...]`表示

当然,从AL寄存器中将数据送入内存只要反过来使用mov就可以了,mov [0],al

如果需要传输字型数,只要使用对应的16位寄存器就可以了,传输的是以相应地址开始的一个字型数据(连续两个字节)。如mov [0],cx

mov,add,sub

mov常见语法:

  1. mov 寄存器,数据 mov ax,8
  2. mov 寄存器,寄存器 mov ax,bx
  3. mov 寄存器,内存单元 mov ax,[0]
  4. mov 内存单元,寄存器 mov [0],ax
  5. mov 段寄存器,寄存器 mov ds,ax
  6. mov 寄存器,段寄存器 mov ax,ds

add,sub常见语法:

  1. add 寄存器,数据 add ax,8
  2. add 寄存器,寄存器 add ax,bx
  3. add 寄存器,内存单元 add ax,[0]
  4. add 内存单元,寄存器 add [0],ax
  5. subadd一样

注意,add,sub不可以操作段寄存器。

栈是一种后进先出的存储空间,从栈顶出栈入栈。LIFO(last in first out)
入栈指令:push ax:表示把ax的内容放到栈中
出栈指令:pop ax:表示把栈顶元素放到ax中

入栈和出栈指令都是以字为单位的。图3.9
image.png

栈寄存器SS,SP与push,pop

CPU通过SS寄存器和SP寄存器来知道栈的范围,段寄存器SS存放的是栈顶的段地址,SP寄存器存放的是栈顶的偏移地址。所以,任意时刻SS:SP指向栈顶元素。

指令push ax执行过程:

  1. sp = sp - 2,ss:sp指向当前栈前面的单元,以当前栈顶前面的单元为新的栈顶。
  2. 将ax中的内容送入ss:sp指向的内存单元处,ss:sp此时指向新栈顶。图3.10

image.png
CPU的SS寄存器保存着栈顶地址,SP保存着偏移地址。入栈时,栈顶从高地址向低地址方向增长。
所以栈顶在低地址,栈底在高地址(8086!!!)。初始状态下,SP指向栈底的下一个单元。

反之pop ax执行过程相反

  1. 将ss:sp指向的内存单元处的数据送入ax。
    1. sp = sp + 2,ss:sp指向当前栈顶下面的单元,以当前栈顶下面的单元为心的栈顶。

8086CPU并不会自己检测push是否会超栈顶,pop是否会超栈底。

push和pop可以加寄存器,段寄存器,内存单元(直接偏移地址[address])

指定栈空间通常通过指定SS来进行,如:

  1. 指定10000H~1000FH为栈空间
  2. mov ax,1000
  3. mov ss,ax
  4. mov sp 0010

注:将一个寄存器清零 sub ax,ax 两个字节,mov ax,0 三个字节
注:若设定一个栈段为10000H~1FFFFH,栈空的时候SP=0(要知道入栈操作先SP-2,然后再送入栈)