首页 > 解决方案 > 没有通过带有 __attribute__((fastcall)) 的寄存器获取从 asm 传递到 C 的函数参数

问题描述

我正在尝试从汇编程序调用 C 函数,但我没有得到按预期传递的值(参数)。

fastcall 属性从 gcc 生成警告并被忽略!

我正在使用 MASM 样式编码并使用 jwasm(或 uasm)进行编译。

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

主程序

#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 上缺少什么!

标签: gccassemblyx86-64calling-convention

解决方案


__attribute__((ms_abi))应该让你的代码做你想做的事。它将告诉 gcc 对该函数使用 Windows x64 调用约定。或者sysv_abi将使用该调用约定来调用该函数(在不是默认设置的平台上)

(但你为什么要这样做?只需像 x86-64 System V 一样在 RDI 中传递参数,然后调用者就不必保留影子空间。)

__attribute__((fastcall))只为 i386 ( -m32) 做任何事情,而不是 x86-64 目标。

GCC 手册的 x86 函数属性页面非常清楚地记录了这一点:在 x86-32 目标上,fastcall 属性...


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


推荐阅读