【问题标题】:Why does leave do "mov esp,ebp" in x86 assembly?为什么在 x86 程序集中留下“mov esp,ebp”?
【发布时间】:2011-07-25 08:46:58
【问题描述】:

据说leave指令同:

mov esp,ebp
pop ebp

但是mov esp,ebp 是为了什么?这对我来说似乎无效......

【问题讨论】:

标签: assembly x86


【解决方案1】:

mov esp,ebp 将堆栈指针设置为基帧地址,从而有效地释放整个帧。 (不要忘记这是 Intel 语法,目标是第一位的。)如果你没有这样做,一旦你调用 ret,你仍然会在调用函数中使用被调用函数的堆栈帧,这会带来崩溃的后果.

【讨论】:

  • 对不起,mov esp,ebp 不是将基指针设置为堆栈指针的地址吗? mov ebp,esp 将更新堆栈指针以指向基帧。
  • @Decave,这取决于您使用的是 AT&T 风格的反汇编还是 Intel 风格的反汇编。由于指令没有长度后缀,并且寄存器没有前缀%,所以我们谈论的是英特尔风格,目的地是第一位的。这个问题的等效 AT&T 样式反汇编,您可能正在考虑以及目的地最后出现的位置,将是 movl %ebp, %esp
  • 啊,当然。非常感谢您的解释。
【解决方案2】:

我认为您的问题是有两种不同的方式来编写 x86 程序集。一种是 AT&T 表示法,另一种是 Intel 表示法。指令参数的顺序在 Intel 表示法中与 AT&T 相反。您的程序集版本似乎采用 Intel 表示法,这意味着 mov esp, ebp 实际上将 ebp 中的值移动到 esp。在更合乎逻辑的(在我看来)AT&T 表示法中,它将是mov %ebp, %esp

【讨论】:

  • 应该是movd 而不是mov
  • 如果您将语义视为move ebp into esp,它“更合乎逻辑”。 “英特尔”表示法(比英特尔早了很长一段时间——例如,可以追溯到 60 年代的 Interdata 16 位系列就使用这种格式,绝不是第一个……)语义更像 @ 987654328@.
  • @zneak,不正确。 movd 实际上是一条 MMX 指令。如果您想包含大小后缀(在这种情况下是可选,请注意),您可以使用movl
  • 事实上英特尔风格的符号更为常见。我知道有目的地的所有其他汇编语言都是第一位的。您可以将其视为一项任务。 esp = ebp
  • 我很早就意识到英特尔 X86 组件使用了我们以前称为逆波兰表示法的东西,这在习惯于在代数,并操作德州仪器的计算器。相反,惠普计算器迎合工程师的需要,并使用逆波兰表示法。当我开始学习使用各种汇编程序时,我很快发现它们中的大多数也使用反向波兰语。其中包括用于 IBM 360/370 类大型机的 Univac Exec-8 汇编和 IBM BAL(基本汇编语言)。
【解决方案3】:

编译器使用该指令释放堆栈中函数使用的空间,leave 指令与mov esp, ebppop ebp 的行为相同。

【讨论】:

  • 肯定enterleave不能都是为了释放堆栈上的已用空间?
  • 是的,你是对的,只是请假指令,我弄错了
猜你喜欢
  • 2011-08-23
  • 2011-01-31
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
相关资源
最近更新 更多