← Home

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都指向栈顶元素。pushpop指令执行时CPU将从SS和SP中获得栈顶的地址。

push 有2步:

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并没有做这样的设计。 它只知道栈顶在哪里。不知道栈有多大。

换个说法就是:只知道下一条指令在哪里,而不知道要处理的指令有多少条。