可能重复:
x86 assembly registers — Why do they work the way they do?
我编写了以下程序:
#include <stdio.h>
int square(int x) {
return x * x;
}
int main() {
int y = square(9);
printf("%d\n", y);
return 0;
}
在OSX上使用GCC 4.2.1进行两次不同的选项:
gcc foo.c -o foo_32.s -S -fverbose-asm -m32 -O1
gcc foo.c -o foo_64.s -S -fverbose-asm -m64 -O1
32位的结果:
_square: ## @square
## BB#0: ## %entry
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
imull %eax, %eax
popl %ebp
ret
对于64位:
_square: ## @square
Leh_func_begin1:
## BB#0: ## %entry
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl %edi, %eax
imull %eax, %eax
popq %rbp
ret
很明显,32位版本从堆栈中检索参数,这是人们对cdecl的期望。但是,64位版本使用EDI
寄存器来传递参数。
这是否违反System V AMD64 ABI,它指定应使用RDI, RSI, RDX, RCX, R8, R9, XMM0–7
寄存器?或者这只是真正的64位值,例如long?
答案 0 :(得分:3)
EDI
只是RDI
的下半部分,因此编译器在RDI
中传递参数,但参数只有32位长,所以它只占用了一半登记册。