我尝试从汇编程序调用 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寄存器中传递函数调用的第一个参数。
我在 mingw gcc + jwasm 和 VS 2015 下测试了它,它工作正常。
我不确定我在 Linux 上错过了什么!
最佳答案
__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
的第二个参数。
关于gcc - 未通过带有 __attribute__((fastcall)) 的寄存器获取从 asm 传递到 C 的函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54435052/