gcc - 未通过带有 __attribute__((fastcall)) 的寄存器获取从 asm 传递到 C 的函数参数

标签 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。

我的理解是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/

相关文章:

qt - 如何使用 gcc 命令单独制作 ffmpeg 可执行文件?

assembly - 如何使用GDB打印复杂寻址模式引用的内存?

c - 兼容 C90 的编译器是否必须考虑 CPU 的指令重新排序?

assembly - native 可执行文件的哪一部分(特别是)使其不可移植?

c++ - 在 x86 中增加一个整数原子吗?

对 gcc -static 选项或其在虚拟机中的行为感到困惑

linux - 为什么 gcc 会生成冗长的汇编代码?

c++ - 与 MinGW (v.4.3.0) 和 libhid 的链接问题

linux - 有没有办法将堆栈上的 `n` 数量的元素克隆到 x86_64 linux 程序集中的堆栈?

gcc - 从Linux交叉编译Windows 64位.exe