【发布时间】: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的一半
-
哦,我不知道。我以为它们是额外的寄存器。