是否有可能说服GCC模仿fastcall调用约定?

是否有可能说服GCC模仿fastcall调用约定?,gcc,visual-c++,Gcc,Visual C++,因此,我有一个程序集需要在windows上使用fastcall调用约定调用函数,但gcc(afaict)不支持它。GCC确实提供了regparm属性,但它期望在eax、edx和ecx中传递前3个参数,而fastcall期望在ecx和edx中传递前两个参数 我只是试图避免有效地复制一些代码路径,因此这并不十分关键,但如果可以避免,那就太好了。如果您是从asm调用函数,那么您肯定可以完全控制调用函数的方式。是什么阻止您加载寄存器并发出调用?GCC通过\uu属性((fastcall))支持快速调用。它

因此,我有一个程序集需要在windows上使用fastcall调用约定调用函数,但gcc(afaict)不支持它。GCC确实提供了regparm属性,但它期望在eax、edx和ecx中传递前3个参数,而fastcall期望在ecx和edx中传递前两个参数


我只是试图避免有效地复制一些代码路径,因此这并不十分关键,但如果可以避免,那就太好了。

如果您是从asm调用函数,那么您肯定可以完全控制调用函数的方式。是什么阻止您加载寄存器并发出
调用

GCC通过
\uu属性((fastcall))
支持
快速调用
。它似乎是在GCC 3.4中引入的。

我知道我在这一点上有点晚了,但如果你们中的任何人偶然发现了这一点,请记住,可以定义一个宏来模拟它。例如:

#if defined(__GNUC__)
    #define MSFASTCALL __fastcall
    #define GCCFASTCALL 
#elif defined(_MSC_VER)
    #define MSFASTCALL
    #define GCCFASTCALL __attribute__((fastcall))
#endif

int MSFASTCALL magic() GCCFASTCALL;
很明显,这看起来有点难看,所以你可以定义两个原型(我就是这么做的),让它更容易阅读,但有些人更喜欢需要更少打字的路线。除特殊情况外,我通常不使用呼叫约定。我只是让编译器优化其余部分


现在,有一些怪癖需要记住。例如,当您针对64位平台时,所有函数都利用fastcall约定,以便利用额外的寄存器,提高速度并降低间接寻址成本。同样,由于fastcall没有标准化,所以不同平台的实现方式也不同。还有一些其他的函数,但这就是我所能想到的。

问题是调用方在汇编程序中,我调用的函数是C语言的——而我调用的函数的编译器代码生成是有问题的:-(啊…是的,我以为你关心的是打电话的人,而不是被叫人。不用担心,我想这就是困惑所在:请注意,真的没有所谓的“the”FASTHELL调用约定。您所描述的与C++ Builder所指的FASTCALL匹配。VisualC++在这个案例中看起来是奇特的,它是值得的。前两个参数是从右向左传递的,分别放置在<代码> EDX < /C>和<代码> ECX < /代码>中吗?“
fastcall
属性使编译器在寄存器ECX中传递第一个参数(如果为整型),在寄存器EDX中传递第二个参数(如果为整型)。“第一个参数和第二个参数的ECX,EDX顺序相同,从左开始。我不确定您为什么要看从右开始的参数…”我不确定您为什么要看从右开始的参数…”我相信这是被调用方如何从右到左传递的。考虑到如果有四个参数,则两个传递到堆栈上,两个在寄存器中传递。参数从左到右传递到堆栈上,而不是寄存器。@jww我看到的每个C调用约定都有一个从最左边的参数到寄存器的固定映射(在cdecl的情况下,可能没有),并且溢出到堆栈的是最右边的参数。现在,大多数调用约定(Pascal除外)让向左的参数比向右的参数在堆栈上的位置更高,这可以看作是将最右边的参数先推到堆栈上。但我从未见过调用约定将最右边的参数放在寄存器中,然后将最左边的参数溢出到堆栈中。