3.8 栈顶超界问题
之前在3.6,3.7我们知道了8086CPU用SS和SP指示栈顶的地址,并提供push和pop指令实现入栈和出栈。在出栈或者入栈时,可能会出现超出栈空间的情况,如下所示:
这里我们引入一个新的概念,栈空间。
栈顶超界是危险的,因为栈空间之外的空间里很可能存放了具有其他用途的数据。CPU在执行push指令的时候考检测栈顶上线寄存器、在执行pop指令时候检测栈底寄存器保证不会超界。
但8086CPU不具有这个功能,它只知道栈顶在何处(SS:SP指示),而不知道我们安排的栈空间的大小。
在编程时要自己操心栈顶超界问题,要根据可能用到的最大栈空间,来安排栈的大小。
3.9 push pop指令
push 和pop指令是可以在寄存器和内存(栈空间也是内存空间的一部分)。格式形式如下:
1 针对寄存器
push 寄存器 ;将一个寄存器中的数据入栈
pop 寄存器 ;出栈,用一个寄存器接收出栈的数据
eg.
push ax
pop ax
2 针对段寄存器
push 段寄存器 ;将一个段寄存器中的数据入栈
pop 段寄存器 ;出栈,用一个段寄存器接收出栈数据
eg.
push ds
pop es
3 针对内存单元
push 内存单元 ;将一个内存字单元处的字入栈(注意:栈操作都是以字为单位)
pop 内存单元 ; 出栈,用一个内存字单元接收出栈的数据
eg.
push [0] ;入栈1000:0处字
pop [2] ;出栈ds:2处
另外, 有个注意事项:
关于如何在10000H处写入字型数据2266H
代码如下:
mov ax, 1000H
mov ss, ax
mov sp, 2 <-++->
mov ax, 2266H
push ax
注意<-++->处,之所以在SP上规定为2, 因为push命令是在栈顶上压入数据,而如果我们要在栈顶上压入新的数据就得先在SP寄存器中先减2。否则如果不指定sp 为2,就无法准确指定10000H处。我们来画一个栈,
10000H |
---|
10001H |
10002H |
… |
1000CH |
1000DH |
1000EH |
1000FH |
10010H |
1000FH为栈的最底处,当SS:SP指针指向10010H时,为空栈。而当我们问题中想要在10000H处push数据,所以我们必须首先调整sp到2(10002H处),这样进行push时候第一步先执行$SP=SP-2$时,就将指针从10002H调整到了10000H处。
另外一个需要注意的事项,十分重要,但很好理解:
出栈的顺序要和入栈的顺序相反