汇编语言栈顶超界的问题

图3.13描述了在执行push指令后,栈顶超出栈空间的情况。
图3.13中,将10010H-1001FH当作栈空间,该栈空间容量为16字节(8字)初始状态中的数据为空,SS=1000H, SP=0020H, SS:SP指向10020H;
在执行8次push ax后,向栈中压入8个字,栈满,SS:SP指向10010H;
再次执行push ax: sp=sp-2. SS:SP指向1000EH,栈顶超出了栈空间,ax送入1 000EH单元处,将栈空间外的数据覆盖。

图3.14描述了在执行pop指令后,栈顶超出栈空间的情况。
图3.14中,将态为满,SS=1000H,10010H-1001FH当作栈空间,该栈空间容量为16字节((8字),当前状 SP=00l0H, SS:SP指向10010H;

511遇见

511遇见

在执行8次pop ax后,从栈中弹出8个字,栈空,SS:SP指向10020H
再次执行pop ax: sp=sp+2, SS:SP指向I 0022H,栈顶超出了栈空间。此后,如果再执行push指令,10020H, 10021 H中的数据将被覆盖。
上面描述了执行push, pop指令时,发生的栈顶超界问题。可以看到,当栈满的时候再使用push指令入栈,或栈空的时候再使用pop指令出栈,都将发生栈顶超界问题。
栈顶超界是危险的,因为我们既然将一段空间安排为栈,那么在栈空间之外的空间里很可能存放了具有其他用途的数据、代码等,这些数据、代码可能是我们自己程序中的,也可能是别的程序中的(毕竟一个计算机系统中并不是只有我们自己的程序在运行)。但是由于我们在入栈出栈时的不小心,而将这些数据、代码意外地改写,将会引发一连串的错误。
我们当然希望CPU可以帮我们解决这个问题,比如说在CPU中有记录栈顶上限和栈底的寄存器,我们可以通过填写这些寄存器来指定栈空间的范围,然后,CPU在执行push指令的时候靠检测栈顶上限寄存器、在执行pop指令的时候靠检测栈底寄存器保证不会超界。
不过,对于8086CPU,这只是我们的一个设想(我们当然可以这样设想,如果CPU是我们设计的话,这也就不仅仅是一个设想)。实际的情况是,8086CPU中并没有这样的寄存器。
8086CPU不保证我们对栈的操作不会超界。这也就是说,8086CPU只知道栈顶在何处(由SS:SP指示),而不知道我们安排的栈空间有多大。这点就好像CPU只知道当前要执行的指令在何处(由CS:1P指示),而不知道要执行的指令有多少。从这两点上我们可以看出8086CPU的工作机理,它只考虑当前的情况:当前的栈顶在何处、当前要执行的指令是哪一条。
我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。


发布日期:

所属分类: 易语言 标签: