x86的替代调用约定

x86的替代调用约定,x86,calling-convention,X86,Calling Convention,是否可以在不修改编译器本身的情况下创建替代调用约定?例如,这个假设的调用约定可以用于优化gcc/clang让他们知道如何将调用约定编译到编译器可执行文件中,而不是由配置文件定义,您可以在不重新编译编译器的情况下覆盖该配置文件 因此,是的,您需要修改编译器,但对于开源编译器来说可能并不难。gcc内部文档中有,记录了如何向编译器描述调用约定。看起来这是在C源代码中完成的,而不是在机器定义文件描述编译器指令集的特殊语言中完成的 我没有检查clang/LLVM如何定义调用约定 但在某些情况下,GNUC

是否可以在不修改编译器本身的情况下创建替代调用约定?例如,这个假设的调用约定可以用于优化

gcc/clang让他们知道如何将调用约定编译到编译器可执行文件中,而不是由配置文件定义,您可以在不重新编译编译器的情况下覆盖该配置文件

因此,是的,您需要修改编译器,但对于开源编译器来说可能并不难。gcc内部文档中有,记录了如何向编译器描述调用约定。看起来这是在C源代码中完成的,而不是在机器定义文件描述编译器指令集的特殊语言中完成的

我没有检查clang/LLVM如何定义调用约定


但在某些情况下,GNUC(gcc/clang/ICC)的灵活性有限。这不是很好,但它不是完全固定的

在x86上,编译器知道多个现有的调用约定。e、 g.x86-64 System V和Windows具有不同的调用约定,您可以使用
\uuuu attribute\uuuuuu((ms_abi))
声明使用Windows约定的函数,即使在为非Windows目标平台编译时也是如此。在编译对函数的调用时,gcc当然会生成代码来传递参数,并根据为函数声明的调用约定设置堆栈

对于32位x86,有许多约定。看

e、 g.您可以使用
\uuuu attribute\uuuu((fastcall))void foo(inta,intb){…}
来声明一个函数,该函数期望它在ECX和EDX中,而不是在堆栈中

甚至还支持(在32位x86上)为调用约定设置寄存器参数的最大数量,使用
\u属性((regparm(3))
来声明一个在寄存器而不是堆栈中最多占用3个整数参数的函数。但是寄存器的顺序是不可配置的,它只使用EAX、ECX和EDX(在大多数约定中被调用的寄存器)

您还可以使用
-mregparm=2
进行编译,以全局设置该值

但是不支持使用阴影空间(如x64窗口)或调用方pops(某些特定的调用方pops约定除外),或使用以标志而不是整数寄存器返回的布尔结果,或使用手写汇编可以执行的任何其他操作来声明要调用的函数



MSVC同样支持vectorcall和regular的一些
\uuuu declspec
选项。

gcc/clang了解如何调用编译到编译器可执行文件中的约定,而不是由配置文件定义,您可以在不重新编译编译器的情况下覆盖该配置文件

因此,是的,您需要修改编译器,但对于开源编译器来说可能并不难。gcc内部文档中有,记录了如何向编译器描述调用约定。看起来这是在C源代码中完成的,而不是在机器定义文件描述编译器指令集的特殊语言中完成的

我没有检查clang/LLVM如何定义调用约定


但在某些情况下,GNUC(gcc/clang/ICC)的灵活性有限。这不是很好,但它不是完全固定的

在x86上,编译器知道多个现有的调用约定。e、 g.x86-64 System V和Windows具有不同的调用约定,您可以使用
\uuuu attribute\uuuuuu((ms_abi))
声明使用Windows约定的函数,即使在为非Windows目标平台编译时也是如此。在编译对函数的调用时,gcc当然会生成代码来传递参数,并根据为函数声明的调用约定设置堆栈

对于32位x86,有许多约定。看

e、 g.您可以使用
\uuuu attribute\uuuu((fastcall))void foo(inta,intb){…}
来声明一个函数,该函数期望它在ECX和EDX中,而不是在堆栈中

甚至还支持(在32位x86上)为调用约定设置寄存器参数的最大数量,使用
\u属性((regparm(3))
来声明一个在寄存器而不是堆栈中最多占用3个整数参数的函数。但是寄存器的顺序是不可配置的,它只使用EAX、ECX和EDX(在大多数约定中被调用的寄存器)

您还可以使用
-mregparm=2
进行编译,以全局设置该值

但是不支持使用阴影空间(如x64窗口)或调用方pops(某些特定的调用方pops约定除外),或使用以标志而不是整数寄存器返回的布尔结果,或使用手写汇编可以执行的任何其他操作来声明要调用的函数



MSVC同样支持vectorcall与常规的一些
\u declspec
选项。

您能更具体地说明您需要什么吗?这似乎不太可能,因为调用约定的作用级别较低,编译器会强制执行自己的规则。@cdarke好吧,我在分析一些汇编代码时遇到了一些非标准的调用约定,它们显然用于优化或混淆,所以我想知道人们会如何着手编写这些汇编代码之一——确切地说。这是您需要使用的级别,而不是C。这完全取决于编译器的开发人员。例如,OpenWatcomC/C++允许您实际定义新的调用约定。使用。它们是该语言的非标准扩展,允许它使用。您能更具体地说明您需要什么吗?这似乎不太可能,因为调用约定的作用级别较低,编译器会强制执行自己的规则。@cdarke好吧,我在分析一些汇编代码时,遇到了一些非标准的调用约定,它们显然用于优化或混淆,所以我想知道如何编写这些汇编代码