使用x86处理器的汇编语言进行堆栈推送和弹出

时间:2017-04-29 08:17:06

标签: assembly stack masm irvine32

我正在学习x86处理器的汇编语言,如果我能正确回答,我希望你有两个问题可以帮我看看。

  1. 关于示例代码运行时会发生什么情况的说法是正确的?
  2.  1: main PROC
     2:      mov edx, 0
     3:      mov eax, 40
     4:      push eax
     5:      call Ex5Sub
     6:      INVOKE ExitProcess, 0
     7: main ENDP
     8: 
     9:Ex5Sub PROC 
    10:      pop eax
    11:      pop edx 
    12:      push eax
    13:      ret 
    14:Ex5Sub ENDP
    

    一个。 EDX将在第6行等于40 湾程序将在第13行的运行时错误停止 C。 EDX将在第6行等于0 d。该程序将在第11行停止运行时错误

    我的答案:(d)因为只有一个元素40被推入堆栈,并且没有其他元素被弹出。

    1. 与此链接Assembly Language 2 Book on Push and Pop中发布的第二个问题相同。我没有足够的声誉来发表评论并询问它。回答这个问题的人说(d)但是我不明白为什么它是(d)从我从书中学到的是,在执行pop eax之后,esp将递增并指向之前的值,所以当它退回时,它应该是10.
    2. 您对我的耐心解释将不胜感激。谢谢

1 个答案:

答案 0 :(得分:3)

#1的答案实际上可以帮助您理解#2而无需对其他问题发表评论。

抱歉,但(d)错了。您假设只有一个元素被推入堆栈是不正确的。第4行的push eax指令将一个元素放入堆栈,但第5行的call Ex5Sub指令将另外一个元素放入堆栈:子例程的返回地址。这就是call指令的作用:它们将返回地址压入堆栈,然后它们跳转到目标。返回地址始终是紧跟在call指令之后的指令的地址,因此在这种情况下,返回地址是第6行的地址。

因此,子程序从堆栈中弹出返回地址,从堆栈弹出40到edx,将返回地址放回堆栈中,然后返回。因此,edx从子程序返回时将保持40,这意味着(a)是正确的。