【问题标题】:Why does GCC not follow the System V AMD64 ABI here? [duplicate]为什么 GCC 在这里不遵循 System V AMD64 ABI? [复制]
【发布时间】:2012-09-18 06:14:17
【问题描述】:

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

使用 GCC 4.2.1 在 OSX 上使用不同选项两次:

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,该 ABI 规定应使用 RDI, RSI, RDX, RCX, R8, R9, XMM0–7 寄存器?还是只有真正的 64 位值(如 long)才会出现这种情况?

【问题讨论】:

  • 有什么问题?它应该在rdi,它在rdi.. 似乎是正确的
  • EDI RDI,同理AX是EAX的一半
  • 哦,我不知道。我以为它们是额外的寄存器。

标签: gcc assembly x86


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 2013-08-10
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多