内存中的字存储
高 8 位存高位字节,低 8 位存低位字节。一个字需要两个连续的内存单元。低位字节存在低地址单元,高位字节存放在高地址单元。
DS 和 [address]
mov 指令可以将一个内存单元中的内容送入一个寄存器。
1 | mov ax, [0] |
[…] 表示内存单元,其中的 0 表示内存单元的偏移地址。指令执行时,8086CPU 自动从 DS 寄存器中取数据作为内存单元的段地址。
1 | mov bx, 1000H |
只能将一个寄存器内的值送入 ds 寄存器。
将 ax 寄存器中的值送入内存单元 10000H:
1 | mov bx, 1000H |
字的传送
在 mov 指令中给出 16 位寄存器就可以进行 16 位数据传送。
1 | mov bx 1000H |
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 | push ax ; 将 ax 寄存器中的数据送入栈(栈空间在内存里面)中 |
8086CPU 中有两个寄存器,段寄存器 SS 和寄存器 SP,栈顶的段地址存在 SS 中,偏移地址存在 SP 中。任意时刻,SS:SP 指向栈顶元素。push 和 pop 指令执行时,CPU 从 SS 和 SP 中得到栈顶地址。
push ax 的执行:
- SP = SP - 2
- 将 ax 寄存器的数送入 SS:SP 指向的内存单元,SS:SP 此时指向新的栈顶
栈顶从高地址向低地址方向增长。
pop ax 的执行:
- 将 SS:SP 指向的内存单元数据送入 ax 寄存器
- 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 倍数的内存单元当做栈空间来使用,从而定义一个栈段。