我正在尝试从汇编器调用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上缺少什么!
答案 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
的第二个参数。