Understand X86 64 calling convention

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>