Calling Convention for 64-bit Unix binaries based on System Five Function arguments are passed in only these registers:
Process
- First 6 arguments are saved into general purpose registers
- Function is called with
call <location>
&rip
pushed - Space is allocated onto the stack for local variables
- Function does work
- Stack is restored
- Returns by calling
ret
- Stack adjusted to remove arguments
Example
With C code:
__attribute__((fastcall)) void printnums(int num1, int num2, int num3){
printf("The numbers you sent are: %d %d %d", num1, num2, num3);
}
int main(){
printnums(1, 2, 3);
return 0;
}
x86 decompilation of main() is:
main:
; stack setup
push ebp
mov ebp, esp
push 3 ; immediate 3 (third argument is pushed to the stack)
mov edx, 0x2 ; immediate 2 (second argument) is copied to edx register.
mov ecx, 0x1 ; immediate 1 (first argument) is copied to ecx register.
call printnums
mov eax, 0 ; return 0
leave
retn
x86 decompilation of printnums() is:
printnums:
; stack setup
push ebp
mov ebp, esp
sub esp, 0x08
mov [ebp-0x04], ecx ; in x86, ecx = first argument.
mov [ebp-0x08], edx ; arg2
push [ebp+0x08] ; arg3 is pushed to stack.
push [ebp-0x08] ; arg2 is pushed
push [ebp-0x04] ; arg1 is pushed
push 0x8065d67 ; "The numbers you sent are %d %d %d"
call printf
; stack cleanup
add esp, 0x10
nop
leave
retn 0x04