3.6 ~ 3.10
《汇编语言(第3版)》3.6 ~ 3.10、《零基础入门学习汇编语言》P16 ~ 19
3.6 栈
栈是一种具有特殊的访问方式的存储空间。它的特殊性就在于,最后进入这个空间的数据,最先出去。
栈有两个基本的操作:入栈和出栈。
- 入栈:将一个新的元素放到栈顶
- 出栈:从栈顶取出一个元素
栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。
栈的操作规则:LIFO(Last In First Out,后进先出)
3.7 CPU 提供的栈机制
8086 CPU 提供相关的指令来以栈的方式访问内存空间。
我们在基于 8086 CPU 编程的时候,可以将一段内存当作栈来使用。
8086 CPU 提供入栈和出栈指令(最基本的):PUSH(入栈)、POP(出栈)
- push ax:将寄存器 ax 中的数据送入栈中;
- pop ax:从栈顶取出数据送入 ax。
8086 CPU 的入栈和出栈操作都是以字为单位进行的。
字型数据用两个单元存放,高地址单元放高 8 位,低地址单元放低 8 位。
8086 CPU 中,有两个寄存器
- 段寄存器 SS:存放栈顶的段地址
- 寄存器 SP:存放栈顶的偏移地址
任意时刻,SS:SP 指向栈顶元素。
push ax
- SP=SP-2
- 将 ax 中的内容送入 SS:SP 指向的内存单元处,SS:SP 此时指向新栈顶。
我们将 10000H~1000FH 这段空间当作栈段,SS=1000H,栈空间大小为 16 字节,栈最底部的字单元地址为 1000:000E。
任意时刻,SS:SP 指向栈顶,当栈中只有一个元素的时候,SS=1000H,SP=000EH。
栈为空,就相当于栈中唯一的元素出栈,出栈后,SP=SP+2,SP 原来为 000EH,加 2 后 SP=10H。所以,当栈为空的时候,SS=1000H,SP=10H。
pop ax
- 将 SS:SP 指向的内存单元处的数据送入 ax 中;
- SP=SP+2,SS:SP 指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
3.9 push、pop 指令
push 和 pop 指令的格式
- 针对寄存器
- push 寄存器:将一个寄存器中的数据入栈
- pop 寄存器:出栈,用一个寄存器接受出栈的数据
- 针对段寄存器
- push 段寄存器:将一个段寄存器中的数据入栈,如:push ds
- pop 段寄存器:出栈,用一个段寄存器接收出栈的数据,如:pop es
- 针对内存单元
- push 内存单元:将一个内存单元处的字入栈(栈操作都是以字为单位)
- pop 内存单元:出栈,用一个内存字单元接收出栈的数据
- 指令执行时,CPU 要知道内存单元的地址,可以在 push、pop 指令中给出内存单元的偏移地址,段地址在指令执行时,CPU 从 ds 中取得。
push 和 pop 指令还要改变 SP 中的内容:push 是先 SP=SP-2,pop 是后 SP=SP+2。push 和 pop 指令同 mov 指令不同,CPU 执行 mov 指令只需一步操作,就是传送,而执行 push、pop 指令却需要两步操作。
push、pop 等栈操作指令,修改的只是 SP。栈顶的变化范围最大为:0~FFFFH
栈的综述
在 SS、SP 中存放栈顶的段地址和偏移地址;提供入栈和出栈指令,他们根据 SS:SP 指示的地址,按照栈的方式访问内存单元
- push 指令的执行步骤
- SP=SP-2
- 向 SS:SP 指向的字单元中送入数据
- pop 指令的执行步骤
- 从 SS:SP 指向的字单元中读取数据
- SP=SP+2
任意时刻,SS:SP 指向栈顶元素。
8086 CPU 只记录栈顶,栈空间的大小我们要自己管理。
3.10 栈段
我们将 10000H~1FFFFH 这段空间当作栈段,SS=1000H,栈空间大小为 64KB,栈最底部字单元地址为 1000:FFFE。任意时刻,SS:SP 指向栈顶,当栈中只有一个元素的时候,SS=1000H,SP=FFFEH。
栈为空,就相当于栈中唯一的元素出栈,出栈后,SP=SP+2。SP 原来为 FFFEH,加 2 后 SP=0,所以,当栈为空的时候,SS=1000H,SP=0。
一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么也不是。