涉及的指令有
pop bx
/* bx = */
完整的 push 和 pop 过程如下
现在 cxuan 问你一个问题,我们上面描述的是 10000H ~ 1000FH 这段空间来作为 push 和 pop 指令的存取单元。但是,你怎么知道这个栈单元就是 10000H ~ 1000FH 呢?也就是说,你如何选择指定的栈单元进行存取?
事实上,8086 CPU 有一组关于栈的寄存器 SS 和 SP。SS 是段寄存器,它存储的是栈的基础位置,也就是栈顶的位置,而 SP 是栈指针,它存储的是偏移地址。在任意时刻,SS:SP 都指向栈顶元素。push 和 pop 指令执行时,CPU 从 SS 和 SP 中得到栈顶的地址。
现在,我们可以完整的描述一下 push 和 pop 过程了,下面 cxuan 就给你推导一下这个过程。
上面这个过程主要涉及到的关键变化如下。
当使用 「PUSH」 指令向栈中压入 1 个字节单元时,SP = SP - 1;即栈顶元素会发生变化;
而当使用 「PUSH」 指令向栈中压入 2 个字节的字单元时,SP = SP – 2 ;即栈顶元素也要发生变化;
当使用 「POP」 指令从栈中弹出 1 个字节单元时, SP = SP 1;即栈顶元素会发生变化;
当使用 「POP」 指令从栈中弹出 2 个字节单元的字单元时, SP = SP 2 ;即栈顶元素会发生变化;
栈顶越界问题现在我们知道,8086 CPU 可以使用 SS 和 SP 指示栈顶的地址,并且提供 PUSH 和 POP 指令实现入栈和出栈,所以,你现在知道了如何能够找到栈顶位置,但是你如何能保证栈顶的位置不会越界呢?栈顶越界会产生什么影响呢?
比如如下是一个栈顶越界的示意图
第一开始,SS:SP 寄存器指向了栈顶,然后向栈空间 push 一定数量的元素后,SS:SP 位于栈空间顶部,此时再向栈空间内部 push 元素,就会出现栈顶越界问题。
栈顶越界是危险的,因为我们既然将一块区域空间安排为栈,那么在栈空间外部也可能存放了其他指令和数据,这些指令和数据有可能是其他程序的,所以如此操作会让计算机懵逼。
我们希望 8086 CPU 能自己解决问题,毕竟 8086 CPU 已经是个成熟的 CPU 了,要学会自己解决问题了。