int func(int i)
{
return i + 1;
}
int main(void)
{
int i = 5;
i = func(i);
return 0;
}
我获得等效的装配代码:
func:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov eax, DWORD PTR [rbp-4]
add eax, 1
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], 5
mov eax, DWORD PTR [rbp-4]
mov edi, eax
call func
mov DWORD PTR [rbp-4], eax
mov eax, 0
leave
ret
我读到,当我这样做时,返回地址被推到堆栈上。 因为这是64位组件,所以我认为此地址为64位宽(即8个字节)。但是,在调查
call func
行的组件时,线
func
似乎暗示返回地址只有4个字节,因为
mov DWORD PTR [rbp-4], edi
将超过堆栈框架的基本指针4个字节。我有一种觉得我从根本上误解了这里发生的事情,我希望得到一些指导。 我期望
[rbp-4]
,但得到了mov DWORD PTR [rbp-8], edi
在调查Func的组件时,线路似乎意味着返回地址只有4个字节,因为
mov DWORD PTR [rbp-4], edi
将超过堆栈框架的基本指针4个字节。
没有。该指令与返回地址无关。 这是关于传递的论点。 特别是,它将传递给参数
mov DWORD PTR [rbp-4], edi
的值复制到我有一种感觉,我从根本上误解了这里发生的事情,我希望得到一些指导。是是的。
指令将返回地址推到堆栈上,包括更新堆栈指针。 当执行时,无论该地址的大小如何,都会将其帧指针设置为返回地址(并且超过了来电者的帧指针的存储值,它将其推到顶部)。 之后,mov
i
func
的堆栈框架中第一个4字节单词的地址。