Understand X86 64 calling convention
System V AMD64 ABI
The calling convention of the System V AMD64 ABI[14] is followed on Solaris, Linux, FreeBSD, Mac OS X, and other UNIX-like or POSIX-compliant operating systems. The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, and R9, while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for floating point arguments. For system calls, R10 is used instead of RCX.[14] As in the Microsoft x64 calling convention, additional arguments are passed on the stack and the return value is stored in RAX.
Registers RBP, RBX, and R12-R15 are callee-save registers; all others must be saved by the caller if they wish to preserve their values.[15]
#include <stdint.h>
typedef int64_t i64;
i64 foo(i64 a0,i64 a1,i64 a2,i64 a3,i64 a4,
i64 a5,i64 a6,i64 a7,i64 a8,i64 a9)
{
return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
}
int main(int argc, char *argv[])
{
foo(0,1,2,3,4,5,6,7,8,9);
return 0;
}
0x0000000000400526 <+15>: pushq $0x9
0x0000000000400528 <+17>: pushq $0x8
0x000000000040052a <+19>: pushq $0x7
0x000000000040052c <+21>: pushq $0x6
0x000000000040052e <+23>: mov $0x5,%r9d
0x0000000000400534 <+29>: mov $0x4,%r8d
0x000000000040053a <+35>: mov $0x3,%ecx
0x000000000040053f <+40>: mov $0x2,%edx
0x0000000000400544 <+45>: mov $0x1,%esi
0x0000000000400549 <+50>: mov $0x0,%edi
0x000000000040054e <+55>: callq 0x4004b6 <foo>