这两条指令在gcc为x86机器生成的汇编代码中产生了什么影响:
push %ebp
movl %esp, %ebp
最佳答案
unwind的解释是字面上的事实(尽管有一个较小的方向性错误),但没有解释原因。%ebp
是您的堆栈框架的“基本指针”。它是C运行时用来访问堆栈上的局部变量和参数的指针。这是GCC生成的一些典型的函数序言代码(准确地说是g++),首先是C++源代码。
// junk.c++
int addtwo(int a)
{
int x = 2;
return a + x;
}
这将生成以下汇编程序。
.file "junk.c++"
.text
.globl _Z6addtwoi
.type _Z6addtwoi, @function
_Z6addtwoi:
.LFB2:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
subl $16, %esp
.LCFI2:
movl $2, -4(%ebp)
movl -4(%ebp), %edx
movl 8(%ebp), %eax
addl %edx, %eax
leave
ret
.LFE2:
.size _Z6addtwoi, .-_Z6addtwoi
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
现在解释一下序言代码(
.LCFI2:
之前的所有内容),首先:pushl %ebp
将调用函数的堆栈框架存储在堆栈中。 movl %esp, %ebp
采用当前的堆栈指针,并将其用作被调用函数的框架。 subl $16, %esp
为局部变量留出空间。 现在,您的功能已准备就绪,可以开始业务了。与
%ebp%
寄存器的偏移为负的任何引用都是您的局部变量(在本示例中为x
)。任何从%ebp%
寄存器偏移正值的引用都是您传入的参数。最后一个有趣的地方是
leave
指令,它是x86汇编程序指令,它负责恢复调用函数的堆栈帧。通常,这已优化为C代码中更快的move %ebp %esp
和pop %ebp%
序列。但是,出于说明目的,我根本没有进行任何优化。
关于gcc - GCC为x86生成的 “push %ebp; movl %esp, %ebp”有什么用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2515598/