没有通过__attribute __((fastcall))通过寄存器将函数参数从asm传递给C

时间:2019-01-30 07:10:37

标签: gcc assembly x86-64 calling-convention

我正在尝试从汇编器调用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。

我的理解是,快速调用应该在RCX寄存器中传递函数调用的第一个参数。

我在mingw gcc + jwasm以及VS 2015上对此进行了测试,效果很好。

我不确定Linux上缺少什么!

1 个答案:

答案 0 :(得分:4)

__attribute__((ms_abi)) 应该使您的代码执行所需的操作。它将告诉gcc为该函数使用Windows x64调用约定。否则sysv_abi将使用该调用约定来调用该函数(在非默认平台上)

(但是为什么要这样做?像在x86-64 System V上一样,只需在RDI中传递arg,则调用者不必保留阴影空间。)

__attribute__((fastcall))仅对i386(-m32)起作用,而不对x86-64目标起作用。

The GCC manual's x86 function attributes page非常清楚地记录了这一点:在x86-32目标上,fastcall属性...


您可以将代码放在https://godbolt.org/上,或在本地查看gcc -O3 -S的输出,并查看其实际复制到RSI的哪个寄存器中,作为printf的第二个参数。