Вам необходимо изучить и следовать соглашениям о вызовах , задокументированным в спецификации Linux x86-64 ABI , в частности ее §3.2.3 Раздел передачи параметров .Таким образом, значение указателя fptr
находится в %rdi
, а значение указателя ret
находится в %rsi
, и вам, вероятно, следует нажать кадр вызова для вашего asmFunc
Читайте также Соглашения о вызовах x86 wikipage.
Если вы можете закодировать эквивалент (даже упрощенный) asmFunc
в C в каком-то файле example.c
, я рекомендую скомпилировать его с gcc -O -fverbose-asm -Wall -S example.c
иищите испущенный example.s
файл ассемблера для вдохновения.В большинстве случаев первая машинная инструкция такой функции - это не call
(а что-то, называемое прологом функции , изменяющий указатель стека %esp
и выделяющий некоторый кадр вызова на стек вызовов )
Например, на моем Linux / Debian / x86-64 с gcc-8
void asmfunc(FILE* fil, char*s) {
fputc ('\t', fil);
fputs (s, fil);
fputc ('\n', fil);
fflush (fil);
}
компилируется в:
.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"
Обратите внимание, что в некоторых случаях GCC может (например, с -O2
) оптимизировать tail-call и может вызывать некоторые leaf-функции специально.