现如今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(X(MPC]3WZGS}~21LT}1(S8.png 我们将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。