栈的概念
栈(stack)是一种具有特殊访问方式的内存空间。栈有两个基本的操作:
- 入栈:将一个新的元素放到栈顶
- 出栈:从栈顶取出一个元素
栈顶的元素总是最后入栈,最先出栈,栈的这种操作规则被称为LIFO(Last In First Out,后进先出)。
CPU允许将一段内存当做栈来使用,这样的内存被称为栈段。
8086CPU中,有两个与栈相关的寄存器:段寄存器 SS 和寄存器 SP 。栈顶的段地址存放在 SS 中,偏移地址存放在 SP 中。任何时候,SS:SP
指向栈顶元素。
SS 是段寄存器,因此不能直接将十六进制数移动到 SS 上,也不能对其使用 ADD 或 SUB 指令。
但是 SP 是普通寄存器,没有这个限制。
注意,8086CPU提供的入栈和出栈操作都是以字为单位进行的。
栈操作:PUSH和POP指令
8086CPU提供的入栈和出栈指令,最基本的两个就是 PUSH 和 POP :
PUSH
data
data
对应的字型数据送入栈顶。
PUSH
container
PUSH 和 POP 指令执行时,CPU从 SS:SP 得到栈顶的地址。
“ PUSH AX
”的执行,由以下两步完成:
- SP-=2 ,SS:SP 指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶
- 将 AX 中的内容送入 SS:SP 指向的内存单元处,SS:SP 此时指向新栈顶
“ PUSH AX
”的执行过程则相反,由以下两步完成:
- 将
SS:SP
指向的内存单元中的数据送入 AX 中 SP+=2
,SS:SP
指向当前栈顶下面的内存单元,以当前栈顶下面的单元为新的栈顶

由于入栈时先改变 SP 再送入数据,出栈时先送出数据再改变 SP ,因此入栈时 SS:SP
指向的内存单元并没有改变(操作的是低2位的字单元),但出栈时,SS:SP
指向的内存数据被直接取出。
栈顶与栈顶越界
PUSH、POP等栈操作指令,修改的只是 SP ,也就是说,栈顶的变化范围最大为0~FFFFH。因此,一个栈段的容量最大为64KB。
CPU只记录栈顶,栈大小、栈空间都是自定的,CPU中不会有相应记录。因此,一般将内存空间中一块无用的16倍数字节大小的空间当做栈使用。
当栈满的时候再使用 PUSH 指令入栈,或当栈空的时候再使用 POP 指令出栈,都会发生栈顶越界问题。
栈顶越界是危险的,因为它可能会覆盖掉其余指令或应用程序的数据,可能引发一连串的错误。