我试着从www.example.com上的一个c++的square函数来理解这godbolt.org。很明显,返回值、参数和局部变量对这个函数使用“rbp - alignment”。有人能解释一下这是怎么可能的吗?那么rbp + alignment在这种情况下会做什么呢?
int square(int num){
int n = 5;// just to test how locals are treated with frame pointer
return num * num;
}
编译器(x86-64 gcc 11.1)
生成的程序集:
square(int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-20], edi. ;\\Both param and local var use rbp-*
mov DWORD PTR[rbp-4], 5. ;//
mov eax, DWORD PTR [rbp-20]
imul eax, eax
pop rbp
ret
2条答案
按热度按时间mxg2im7a1#
在这种情况下,区分参数和实参是很方便的。简而言之:参数是由调用者给出的 * 值 *,而参数是保存它们的 * 变量 *。
当呼叫
square
时,呼叫端会根据标准x86-64呼叫惯例,将 argument 放入rdi
寄存器。square
接着会配置局部变量 parameter,并将参数放入parameter中。这可让参数像任何其他变数一样使用:由于在这种情况下是被调用方为参数分配内存,因此它必须驻留在帧指针之下。在ABI中,参数是在堆栈上传递的,被调用方可以重用包含参数的堆栈槽作为参数。这正是x86-32上发生的事情(传递
-m32
来查看自己):当然,如果启用了优化,编译器就不会为在被调用方的堆栈上分配参数而烦恼;它将直接使用寄存器中的值:
rqmkfv5c2#
GCC允许“leaf”函数,那些不调用其他函数的函数,不需要创建堆栈框架。自由堆栈是一个公平的游戏,可以满足这些fns的愿望。