Не получается передать параметры функции из asm в C через регистры с __attribute __ ((fastcall)) - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь вызвать функции C из ассемблера, но я не получаю значения (параметры), переданные должным образом.

Атрибут fastcall генерирует предупреждение от gcc и игнорируется!

Я использую кодирование в стиле MASM и компилирую его с помощью jwasm (или uasm).

jwasm -q -10 -elf64 -mf -zf0 asmfunc.asm -Fo asmfunc.o

main.c

#include <stdio.h>

__attribute__((fastcall)) void DumpRCX(unsigned long long rcx)
{
    printf("%llx\n", rcx);
}

void asmfunc(void);

main(arc, *argv[])
{
    asmfunc();
}

asmfunc.asm

EXTERN  DumpRCX: PROC

PUBLIC asmfunc
asmfunc PROC
    sub rsp, 28h
    mov rcx, 84h ; any value for testing
    call DumpRCX
    add rsp, 28h
    ret
asmfunc ENDP

Он запускается и входит в функцию DumpRCX, но значение в RCX никогда не равно 84h.

Насколько я понимаю, fastcall должен передать первый аргумент вызова функции в регистре RCX.

Iпроверил это под mingw gcc + jwasm, а также VS 2015, и все работает нормально.

Я не уверен, что мне не хватает в Linux!

1 Ответ

0 голосов
/ 30 января 2019

__attribute__((ms_abi)) должен заставить ваш код делать то, что вы хотите.Он скажет gcc использовать соглашение о вызовах Windows x64 для этой функции.Или sysv_abi будет использовать это соглашение о вызовах для вызовов этой функции (на платформах, где это не по умолчанию)

(Но зачем вам это делать? Просто передайте arg в RDI, как обычно для системы x86-64.V, тогда вызывающему не нужно резервировать теневое пространство.)

__attribute__((fastcall)) делает что-то только для i386 (-m32), но не для целей x86-64.

Страница атрибутов функции x86 руководства GCC довольно четко описывает это: Для целей x86-32 атрибут fastcall ...


Вы можетепоместите ваш код на https://godbolt.org/ или посмотрите на gcc -O3 -S вывод локально и посмотрите, какой регистр он фактически копирует в RSI как 2-й аргумент для printf.

...