【问题标题】:Stack push and pop in assembly language for x86 processors用于 x86 处理器的汇编语言中的堆栈推送和弹出
【发布时间】:2017-09-27 08:24:31
【问题描述】:

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

  1. 关于示例代码运行时会发生什么,哪项陈述是正确的?
 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 将递增并指向以前的值,所以ret的时候应该是10。

感谢您耐心地向我解释。谢谢你

【问题讨论】:

  • 安装 Visual Studio 并试用 :-) 问题来自 Irvine 的书。在他的主页上有安装和使用 VS 的提示:kipirvine.com/asm
  • 感谢您告诉我这些信息和链接!

标签: assembly stack masm irvine32


【解决方案1】:

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

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

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

【讨论】:

  • 您好,感谢您的回复。你能帮我确认一下我的理解是否正确吗?所以在第 5 行,此时堆栈有 40 ,然后 pop eax = pop 40,pop edx = 将 40 保存到 edx 中?因为书中的示例(例如,pop eax 是一个数字然后使用 mov 复制到另一个变量)我从未见过 pop edx(pop reg) 作为直接将值复制到 edx 的方式。所以我不确定是不是这样。如果我错了,请纠正。在第 12 行 push eax 时,是否将返回地址放回堆栈中?所以这意味着在这个子程序中 eax 和 edx 都是 40?
  • 我从书中看到,当一个过程返回一个寄存器中的值时不应该被压入或弹出,所以在第 10 行表示它恢复 eax,所以 pop edx 用于存储弹出时的 40 edx 也意味着恢复 edx?如果您能向我解释,我将不胜感激。非常感谢
  • 不,pop eax = pop address-of-line-6,然后是pop edx = 40 -> edx。是的,push eax = push address-of-line-6。不,eaxedx 具有不同的值
  • 第 10 行不会恢复eax,它会通过从堆栈中弹出一个值来破坏包含的任何eax,无论如何这是子程序的开始,它与子程序返回值。
  • 看:这个子程序非常规,我们不会像那样从堆栈中弹出东西,当然不是返回地址,所以先生。欧文选择了一种高度非教学的方式来教授他想教的任何东西。他已经成功地迷惑了你。
猜你喜欢
  • 2014-08-04
  • 2015-06-20
  • 2017-01-21
  • 1970-01-01
  • 2012-04-05
  • 2022-07-22
  • 2013-11-05
  • 1970-01-01
  • 2013-05-17
相关资源
最近更新 更多