据说 leave
指令与:
mov esp,ebp
pop ebp
但是这里的 mov esp,ebp
是做什么用的?这对我来说似乎无效...
mov esp,ebp
将堆栈指针设置为基帧地址,从而有效地释放整个帧。 (不要忘记这是 Intel 语法,目的地是第一位的。)如果你没有这样做,一旦你调用 ret
,你仍然会在调用函数中使用被调用函数的堆栈帧,这会带来崩溃的后果.
我认为您的问题是有两种不同的编写 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}。
movd
实际上是一条 MMX 指令。如果您想包含大小后缀(在这种情况下是可选,请注意),您可以使用 movl
esp = ebp
编译器使用该指令释放堆栈中函数使用的空间,leave
指令与 mov esp, ebp
和 pop ebp
具有相同的行为。
enter
和 leave
不能两者都是为了释放堆栈上的已用空间?
mov esp,ebp
没有将基指针设置为堆栈指针的地址吗?mov ebp,esp
将更新堆栈指针以指向基帧。%
前缀,所以我们谈论的是 Intel 风格,其中目的地是第一位的。这个问题的等效 AT&T 样式反汇编,您可能正在考虑以及目的地最后出现的位置,将是movl %ebp, %esp
。