此问题已在此处有答案:
Why are parameters allocated below the frame pointer instead of above?(2个答案)
上个月关门了。
int square(int num, int i2) {
return num * num;
}
square(int, int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov DWORD PTR [rbp-8], esi
mov eax, DWORD PTR [rbp-4]
imul eax, eax
pop rbp
ret
我们知道堆栈是从高地址到低地址增长的,我看到书上当函数调用发生时,堆栈可能像函数参数,然后返回地址,然后旧的ebp。但为什么rbp - 4是第一个参数地址,而不是rbp + 4,因为参数保持在高地址
能给我解释一下吗?
2条答案
按热度按时间4jb9z9bj1#
64位ABI -前6个参数在寄存器中传递,不在堆栈上。
所以要查看参数是如何从堆栈中取出的,你需要有更多的参数:
和代码:
如您所见,参数
n7
是从堆栈DWORD PTR [rsp+8]
中获取的在32位系统上:
所有参数都取自堆栈。
为什么x86汇编函数调用的第一个参数是rbp - 4而不是rbp + 4
因为你编译它没有优化和编译器提供了自动存储这些参数是通过在寄存器。
x86-64编译的相同代码,没有优化:
(C)copyright - https://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/ posted without any permission
qncylg1j2#
寄存器
rbp
存储堆栈的当前地址。就像你自己写的我们知道堆栈是从高地址向低地址增长
因此,为了为作为函数的局部变量的参数分配存储器,
rbp + 4
寻址不属于函数的调用者的内存。在这个简单的函数中可以看到,参数通过寄存器edi
和esi
传递给函数,这些寄存器存储在函数的参数(局部变量)中。如果参数的数量大于编译器用来存储参数的寄存器的数量,那么在这种情况下,要访问函数中的参数,可以向rbp
添加一个正值,以访问调用者存储在堆栈中的参数。通过寄存器传递参数更有效。