现如今CPU中都有栈的设计,该机制灵活且适用于各类存储空间。8086CPU提供相关指令来以栈的方式访问内存空间。这意味着,我们在基于8086编程的时候,可以将一段内存当作栈来使用。
8086CPU提供的最基本的入栈和出栈指令:
PUSH (入栈)
POP (出栈)
PUSH ax:将寄存器ax中的数据送入栈中;
POP ax:从栈顶取出数据送入ax。
8086CPU的入栈和出栈都是以字为单位进行的。注意:字型数据用两个单元存放,高地址单元放高8位,低地址
单元放低8位。
两个疑问:
1、CPU如何知道一段内存空间被当作栈使用?
2、执行push和pop的时候,如何知道哪个单元是栈顶单元?
分析:
1、寄存器CS和IP中存放着当前指令的段地址和偏移地址。8086CPU中,有两个寄存器:
段寄存器SS 存放栈顶的段地址
寄存器SP 存放栈顶的偏移地址
结论:任意时刻,SS:SP指向栈顶元素。
2、push ax
(1)SP=SP-2;
(2)将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。
![~5@A}JD8MMXXVZDXSC%T`O.png pop指令反之,先弹出,后指针加2。执行pop后原位置数据依然存在,但执行过下一轮push后会将其覆盖。
问题:如果我们将10000H~1000FH这段空间当作栈,初始状态为空,此时,SS=1000H,SP=?
分析:SP=0010H 我们将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。
换个角度看:
任意时刻,SS:SP指向栈顶元素,当栈为空的时候,栈中没有元素,也就不存在栈顶元素,所以SS:SP只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2,栈最底部字单元的地址为1000:000E,所以栈空时,SP=0010H。