内存中的字存储

高 8 位存高位字节,低 8 位存低位字节。一个字需要两个连续的内存单元。低位字节存在低地址单元,高位字节存放在高地址单元。

DS 和 [address]

mov 指令可以将一个内存单元中的内容送入一个寄存器。

1
mov ax, [0]

[…] 表示内存单元,其中的 0 表示内存单元的偏移地址。指令执行时,8086CPU 自动从 DS 寄存器中取数据作为内存单元的段地址。

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

只能将一个寄存器内的值送入 ds 寄存器。

将 ax 寄存器中的值送入内存单元 10000H:

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

字的传送

在 mov 指令中给出 16 位寄存器就可以进行 16 位数据传送。

1
2
3
4
mov bx 1000H
mov ds, bx
mov ax, [0] ; 1000:0 处的字型数据送入 ax 寄存器
mov [0], cx ; cx 寄存器的数据送入 1000:0 处

mov、add、sub 指令

指令 参数一 参数二
mov ax, 8 寄存器 数据
mov ax, bx 寄存器 寄存器
mov ax, [0] 寄存器 内存单元
mov [0], ax 内存单元 寄存器
mov ds, ax 段寄存器 寄存器
mov ax, ds 寄存器 段寄存器
mov [0], cs 内存单元 段寄存器
mov ds, [0] 段寄存器 内存单元

数据段

可以将一组长度为 N、地址连续、起始地址为 16 倍数的内存单元当做专门存储数据的内存空间,从而定义一个数据段。

可以用 ds 存储数据段的起始地址,再用 [偏移地址] 访问数据段中的具体单元。

检测点 3.1

AX = 2262H
BX = E626H
AX = E626H
AX = 2662H
BX = D6E6H
AX = FD48H
AX = 2C14H
AX = 0H
AX = 00E6H
BX = 0H
BX = 0026H
AX = 000CH

LIFO。应该有一个标记,指向栈顶。

8086CPU 提供相关指令以栈的方式使用一段内存空间。入栈出栈操作以字为单位进行。

1
2
push ax  ; 将 ax 寄存器中的数据送入栈(栈空间在内存里面)中
pop ax ; 将栈顶元素取出送入 ax 寄存器

8086CPU 中有两个寄存器,段寄存器 SS 和寄存器 SP,栈顶的段地址存在 SS 中,偏移地址存在 SP 中。任意时刻,SS:SP 指向栈顶元素。push 和 pop 指令执行时,CPU 从 SS 和 SP 中得到栈顶地址。

push ax 的执行:

  1. SP = SP - 2
  2. 将 ax 寄存器的数送入 SS:SP 指向的内存单元,SS:SP 此时指向新的栈顶

入栈

栈顶从高地址向低地址方向增长。

pop ax 的执行:

  1. 将 SS:SP 指向的内存单元数据送入 ax 寄存器
  2. SP = SP + 2,更新栈顶地址

出栈

栈顶超界问题

当栈满时 push 或栈空时 pop,会导致栈顶越界,从而写入数据时覆盖其他内存单元。需要自己操心栈顶越界问题,8086CPU 不提供防御。

push 和 pop 指令

push 和 pop 指令可以在内存与寄存器之间传递数据。

push 寄存器 ; 将一个寄存器中的数据入栈

pop 寄存器 ; 用一个寄存器接受出栈的数据

push 段寄存器

pop 段寄存器

在内存单元之间传递数据。

push 内存单元

pop 内存单元

push 和 pop 访问的内存单元地址不是在指令中给出的,而是由 SS:SP 指出的。push、和 pop 还会改变 SP 中的内容。

执行 push 时,CPU 先改变 SP,后向 SS:SP 处传送。执行 pop 时,CPU 先读取 SS:SP 处的数据,后改变 SP。

栈段

我们可以将长度为 N(N ≤ 64KB)的一组地址连续、起始地址为 16 倍数的内存单元当做栈空间来使用,从而定义一个栈段。