在GNU/Linux上遵循System V AMD64 ABI的调用约定。寄存器RDI、RSI、RDX、RCX、R8和R9用于整数和内存地址参数,XMM0、XMM1、XMM2、XMM3、XMM4、XMM5、XMM6和XMM7用于浮点参数。
对于系统调用,使用R10而不是RCX。附加参数在堆栈上传递,返回值存储在RAX中。
Michael Matz, Jan Hubicka, Andreas Jaeger 和 Mark Mitchell。System V应用程序二进制接口AMD64架构处理器补充。0.99.6:
http://x86-64.org/documentation/abi.pdf
来自 Wikipedia 的x86调用约定:
http://en.wikipedia.org/wiki/X86_calling_conventions#cite_note-AMD-9
函数一:add(x, y) => x + y;
int add(int x, int y) { return x+y; }
x86_64 clang 6.0.0
add(int, int): # @add(int, int)
lea eax, [rdi + rsi]
ret
x86_64 gcc 4.9.4
add(int, int):
lea eax, [rdi+rsi]
ret
函数二:
int select(int b, int a1, int a2) { return b ? a1 : a2; }
x86_64 clang 6.0.0
select(int, int, int): # @select(int, int, int)
test edi, edi
cmove esi, edx
mov eax, esi
ret
x86_64 gcc 4.9.4
select(int, int, int):
test edi, edi
mov eax, edx
cmovne eax, esi
ret
注意:
EDI 寄存器是 RDI 寄存器的低地址值(短)
RDI 寄存器一次可以读/写8字节二进制数据,EDI 寄存器一次可以读写4字节二进制数据,在早年的X86/32位CPU机器上面表示8字节在寄存器内需要占用两个寄存器,C/C++ 内部顶一个长整数的数据结构,【例如】LARGE_INTEGER
长整数(8字节)
struct LARGE_INTEGER {
DWROD dwLow;
DWROD dwHigh;
};
EDI 寄存器在 X86_64 的汇编里面,它等价于 LARGE_INTEGER 的 dwLow 字段存储值部分,共享一个8字节的寄存器单元。(64位处理器寄存器都是8字节一个单元,32位处理器是4字节一个单元。)