2012-09-26 65 views
2

可能重复:
x86 assembly registers — Why do they work the way they do?为什么GCC不在这里遵循System V AMD64 ABI?

我整理了以下程序:

#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位值的情况下长?

+3

什么问题?它应该在'rdi'中,它在'rdi' ..似乎是正确的 – harold

+3

EDI *是* RDI,只有一半以相同的方式AX是EAX的一半 – Flexo

+0

哦,我不知道。我认为他们是额外的登记册。 – Overv

回答

2

EDI只是RDI的下半部分,所以编译器传递的参数是RDI,但是参数只有32位长,所以只占用寄存器的一半。