2

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?

Community
  • 1
  • 1
Overv
  • 8,433
  • 2
  • 40
  • 70

1 Answers1

3

EDI is simply the lower half of RDI so the compiler is passing the argument in RDI, but the argument is only 32-bits long, so it only takes up half of the register.

Dirk Holsopple
  • 8,731
  • 1
  • 24
  • 37