SS:SP鸡你太美存器
6 April, 2020
如今的CPU都有提供栈机制,8086也不例外。
8086提供的最基本的两个指令就是push
and pop
.
push ax ;将寄存器ax中的数据送入栈顶
pop ax ;将栈顶的数据送入ax
我们知道CS:IP寄存器存放了下一条指令的段地址和偏移地址,那么CPU是如何知道栈顶在哪呐? 显然也有两个寄存器专门存放栈顶的地址,那就是SS:SP寄存器,SS = 段地址, SP = 偏移地址
任意时刻,SS:SP都指向栈顶元素。push
和pop
指令执行时CPU将从SS和SP中获得栈顶的地址。
push
有2步:
- SP -= 2 SS:SP指向栈顶前面的单元,以这个位置为新栈。
- 将AX中的内容送入 SS:SP 所指的位置.
10000H |_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
1000EH |__23___| <= SS:SP
1000FH |__01___|
10000H |_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______| <= SS:SP: 换个位置
|_______|
1000EH |__23___|
1000FH |__01___|
10000H |_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______| ;来自ax寄存器的数据
|__54___| <= SS:SP: 换个位置
|__11___|
1000EH |__23___|
1000FH |__01___|
假设 10000H -> 1000FH 这段空间是栈,那么栈空时,SS:SP在呐?
10000H |_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
1000EH |_______|
1000FH |_______| <= SS:SP: 我在这?
10000H |_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
|_______|
1000EH |_______|
1000FH |_______|
10010H |_______| <= SS:SP: 其实爷在这里。
至于为什么只要想想 SP -= 2
你就知道了。
关于爆栈
栈一旦爆了,SS:SP就会指到别的地方去。 这么一想CPU应该会知道栈顶在哪里。
每次push
,pop
都会检查栈顶和栈底的位置,保证栈不会超。这么一想美滋滋。
然而,8086CPU并没有做这样的设计。 它只知道栈顶在哪里。不知道栈有多大。
换个说法就是:只知道下一条指令在哪里,而不知道要处理的指令有多少条。