ChatGPT解决这个技术问题 Extra ChatGPT

为什么在 x86 程序集中留下“mov esp,ebp”?

据说 leave 指令与:

mov esp,ebp
pop ebp

但是这里的 mov esp,ebp 是做什么用的?这对我来说似乎无效...


A
Andrew Barber

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


抱歉,mov esp,ebp 没有将基指针设置为堆栈指针的地址吗? mov ebp,esp 将更新堆栈指针以指向基帧。
@Decave,这取决于您是使用 AT&T 风格的反汇编还是英特尔风格的反汇编。由于指令没有长度后缀,寄存器也没有 % 前缀,所以我们谈论的是 Intel 风格,其中目的地是第一位的。这个问题的等效 AT&T 样式反汇编,您可能正在考虑以及目的地最后出现的位置,将是 movl %ebp, %esp
啊,当然。非常感谢您的解释。
您的网站 felixcloutier.com/x86 已关闭(整个域也是如此)。您打算恢复它,还是应该开始编辑旧答案中的链接? (不幸的是,链接说明的旧评论不可编辑。)
@PeterCordes DNS 出于可悲的原因没有自动更新,应该在 TTL 过期并刷新后立即恢复在线。 (它已经为我重新上线了。)
A
Abhay Buch

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


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

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


肯定 enterleave 不能两者都是为了释放堆栈上的已用空间?
是的,你是对的,只是请假指令,我犯了一个错误