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.