You need to learn and follow the calling conventions documented in Linux x86-64 ABI specification, in particular its §3.2.3 Parameter passing section. So the pointer value fptr
is in %rdi
, and the pointer value ret
is in %rsi
and you probably should push a call frame for your asmFunc
Read also the x86 calling conventions wikipage.
If you are able to code the equivalent (even a simplified one) of asmFunc
in C in some example.c
file, I recommend compiling it with gcc -O -fverbose-asm -Wall -S example.c
and looking into the emitted example.s
assembler file for inspiration. Most of the time, the first machine instruction of such a function is not a call
(but something, called the function prologue, changing the stack pointer %esp
and allocating some call frame on the call stack)
For example, on my Linux/Debian/x86-64 with gcc-8
void asmfunc(FILE* fil, char*s) {
fputc ('\t', fil);
fputs (s, fil);
fputc ('\n', fil);
fflush (fil);
}
is compiled into:
.text
.globl asmfunc
.type asmfunc, @function
asmfunc:
.LFB11:
.cfi_startproc
pushq %rbp #
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
pushq %rbx #
.cfi_def_cfa_offset 24
.cfi_offset 3, -24
subq $8, %rsp #,
.cfi_def_cfa_offset 32
movq %rdi, %rbx # fil, fil
movq %rsi, %rbp # s, s
# /tmp/example.c:4: fputc ('\t', fil);
movq %rdi, %rsi # fil,
movl $9, %edi #,
call fputc@PLT #
# /tmp/example.c:5: fputs (s, fil);
movq %rbx, %rsi # fil,
movq %rbp, %rdi # s,
call fputs@PLT #
# /tmp/example.c:6: fputc ('\n', fil);
movq %rbx, %rsi # fil,
movl $10, %edi #,
call fputc@PLT #
# /tmp/example.c:7: fflush (fil);
movq %rbx, %rdi # fil,
call fflush@PLT #
# /tmp/example.c:8: }
addq $8, %rsp #,
.cfi_def_cfa_offset 24
popq %rbx #
.cfi_def_cfa_offset 16
popq %rbp #
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE11:
.size asmfunc, .-asmfunc
.ident "GCC: (Debian 8.3.0-6) 8.3.0"
Notice however that in some cases, GCC is capable (e.g. with -O2
) of tail-call optimizations and might call some leaf-functions specially.