春卷の爱 发表于 2014-2-9 07:54:14

第三章 栈寄存器SP=2,push ax 程序出错

本帖最后由 春卷の爱 于 2014-2-9 08:32 编辑

PUSH指令的执行,由两步完成:1. SP=SP-2
2. push reg

运行DEBUG
设置SP=0000,PUSH AX,SP变为FFFE
设置SP=0002,PUSH AX,结果程序出错,请问这是为什么?在真实的汇编环境下,SP=2运行PUSH指令,会在栈的段地址内循环吗(SS不变,SP=0002 -> SP=0000 -> SP=FFFE)?


补充:设置SP=0001,PUSH AX,也会出错:

zouyang 发表于 2014-2-9 11:08:43

不懂的,等待高手吧

春卷の爱 发表于 2014-2-9 14:15:33

本帖最后由 春卷の爱 于 2014-2-9 14:34 编辑

郁闷了,做到问题3.10的时候,设置SP=2,一PUSH就死机。
按照问题3.12后面的分析: PUSH, POP指令在执行的时候只修改SP,所以栈顶的变化范围是0-FFFFH,从栈空的时候SP=0,一直压栈,到栈满时SP=FFFE ->SP=0000,栈顶将环绕,覆盖了原来的内容。

所以一个栈的数据不会溢出到其他段,而是反复更新64KB范围内栈段的数据。

oggplay 发表于 2014-2-9 15:30:23

本帖最后由 oggplay 于 2014-2-9 15:47 编辑

pushw%ax #等于sp-4好么?所以当sp=0说明堆栈满了,再push一次就溢出了,你手动赋值就应该是:
       movw    $0xffff,%bx
       movw    %bx,   %sp
       pushw   %ax
或者 addw    $8,%sp
       pushw    %ax
这样就不会出错了
(请不要在意我的汇编写法,理解意思是主要的)

春卷の爱 发表于 2014-2-9 23:25:31

oggplay 发表于 2014-2-9 15:30 static/image/common/back.gif
pushw%ax #等于sp-4好么?所以当sp=0说明堆栈满了,再push一次就溢出了,你手动赋值就应该是:
       m ...

谢谢回复,代码不太看得懂,但你的意思我大概理解了。

我想请问一下堆栈溢出为什么会有错误提示。

问题3.12的分析部分说,“PUSH POP指令只修改SP,所以栈顶的变化范围是0-FFFFH,栈空的时候SP=0,一直PUSH,知道栈满时SP=0,如果再次PUSH,栈顶将环绕,覆盖了原来栈中的内容”

按照书上的说法是堆栈溢出以后SP会环绕,但不会报错。但我的SP PUSH到底以后出错了。不知道是不是DEBUG环境下特有的问题。我想学到后面我应该可以在真实程序里验证一下。
页: [1]
查看完整版本: 第三章 栈寄存器SP=2,push ax 程序出错