Possible Duplicate:
x86 assembly registers — Why do they work the way they do?
I've compiled the following program:
#include <stdio.h>
int square(int x) {
return x * x;
}
int main() {
int y = square(9);
printf("%d\n", y);
return 0;
}
two times with different options on OSX with 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
The result for 32 bit:
_square: ## @square
## BB#0: ## %entry
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
imull %eax, %eax
popl %ebp
ret
And for 64-bit:
_square: ## @square
Leh_func_begin1:
## BB#0: ## %entry
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl %edi, %eax
imull %eax, %eax
popq %rbp
ret
As is evident, the 32-bit version retrieves the parameter from the stack, which is what one would expect with cdecl. The 64-bit version however uses the EDI
register to pass the parameter.
Doesn't this violate the System V AMD64 ABI, which specifies that the RDI, RSI, RDX, RCX, R8, R9, XMM0–7
registers should be used? Or is this only the case for true 64-bit values like long?