为什么GCC不遵循System V AMD64 ABI?

时间:2012-09-26 15:06:11

标签: gcc assembly x86

  

可能重复:
  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?

1 个答案:

答案 0 :(得分:3)

EDI只是RDI的下半部分,因此编译器在RDI中传递参数,但参数只有32位长,所以它只占用了一半登记册。