查看汇编程序时(请参见上的
godbolt.org
extern int global;
void doit(int *);
void call_doit(){
doit(&global);
}
32位值用于保存
global
call_doit:
movl $global, %edi
jmp doit
我知道,使用32位寄存器(即。
%edi
)这里优于64位寄存器(即。
%rdi
movl $global, %edi
需要5个字节
movq $global, %rdi
需要7个字节+4个额外的字节,如果你不认为
$global
适合32位)。
lea global(%rip), %rdi
从RIP+32位相对位移创建一个64位地址,由于相关原因,编译器可以假定它在范围内。以及
movabs $global, %rdi
但是为什么编译器可以假设全局变量的地址适合这32位呢?编译器有什么保证?
对于局部变量,编译器使用64位寄存器来保存堆栈地址,例如:
void doit(int *);
void call_doit(){
int local=0;
doit(&local);
}
结果(请参见上的
godbolt.org
):
call_doit:
subq $24, %rsp
leaq 12(%rsp), %rdi
movl $0, 12(%rsp)
call doit
addq $24, %rsp
ret