Okay, so far I’ve figured that there are six registers used for the first 6 parameters used in a function call. The below c program sets up the function which also uses RAX as the return value:
#include
#include
int asmparams(int, int, int, int, int, int);
int main(void) {
int ret = asmparams(1, 2, 3, 4, 5, 6);
printf("return:%d\n", ret);
return EXIT_SUCCESS;
}
This now expects my assembler function to take 6 arguments and a return value. Below is how those first 6 arguments are used in 64 bit Unix function calls to assembler.
section .text
global asmparams:function
extern printf
printnum:
push rbp ; stack frame? x64
push rsi
push rdx
push rcx
push r8
push r9
mov rsi,rax
mov rdi,pf_msg
xor rax,rax
call printf
pop r9
pop r8
pop rcx
pop rdx
pop rsi
pop rbp ; stack frame
ret
asmparams:
mov rax, rdi
call printnum
mov rax, rsi
call printnum
mov rax, rdx
call printnum
mov rax, rcx
call printnum
mov rax, r8
call printnum
mov rax, r9
call printnum
mov rax, -1 ; return value
ret
section .data
pf_msg db "%08x",10,0
When I’ve got some time to explore how the ‘Prologue’ and ‘Epilogue’, or beginning and ending of a function, I post about that. At least now parameters can be passed to assembler functions.
Things have changed a lot since the 680×0 days. Then you could use a single push/pop instruction to push/pop multiple registers.