简体   繁体   English

我可以编写同时使用GCC和MSVC构建的(x86)汇编语言吗?

[英]Can I write (x86) assembly language which will build with both GCC and MSVC?

I have a project which is entirely written in C. The same C files can be compiled using either GCC for Linux or MSVC for Windows. 我有一个完全用C编写的项目。可以使用Linux的GCC或Windows的MSVC来编译相同的C文件。 For performance reasons, I need to re-write some of the code as x86 assembly language. 出于性能原因,我需要将某些代码重新编写为x86汇编语言。

Is it possible to write this assembly language as a source file which will build with both the GCC and MSVC toolchains? 是否可以将此汇编语言编写为将与GCC和MSVC工具链一起构建的源文件? Alternatively, if I write an assembly source file for one toolchain, is there a tool to convert it to work with the other? 或者,如果我为一个工具链编写了一个程序集源文件,是否有工具可以将其转换为可与另一个工具链一起使用?

Or, am I stuck either maintaining two copies of the assembly source code, or using a third-party assembler such as NASM ? 或者,我是否坚持维护汇编源代码的两个副本,还是使用诸如NASM之类的第三方汇编程序?

I see two problems: 我看到两个问题:

  • masm and gas have different syntax. masm和gas具有不同的语法。 gas can be configured to use Intel syntax with the .syntax intel,noprefix directive, but even then small differences remain (such as, different directives). 可以将gas配置为与.syntax intel,noprefix指令一起使用Intel语法,但是即使这样,仍然存在很小的差异(例如,不同的指令)。 A possible approach is to preprocess your assembly source with the C preprocessor, using macros for all directives that differ between the two. 一种可能的方法是使用C预处理器对汇编源进行预处理,并对这两者之间不同的所有指令使用宏。 This also has the advantage of providing a unified comment syntax. 这也具有提供统一注释语法的优点。

    However, just using a portable third party assembler like nasm is likely to be less of a hassle. 但是,仅使用像nasm这样的便携式第三方汇编程序就不会那么麻烦了。

  • Linux and Windows have different calling conventions. Linux和Windows具有不同的调用约定。 A possible solution for x86-32 is to stick to a well-supported calling convention like stdcall . x86-32的可能解决方案是坚持使用受支持的调用约定,例如stdcall You can tell gcc what calling convention to use when calling a function using function attributes . 您可以告诉gcc使用函数属性调用函数时使用哪种调用约定。 For example, this would declare foo to use the stdcall calling convention: 例如,这将声明foo使用stdcall调用约定:

     extern int foo(int x, int y) __attribute__((stdcall)); 

    You can do the same thing in MSVC with __declspec , solving this issue. 您可以使用__declspec在MSVC中执行相同的操作,从而解决此问题。

    On x86-64, a similar solution is likely possible, but I'm not exactly sure what attributes you have to set. 在x86-64上,可能有类似的解决方案,但是我不确定您必须设置哪些属性。

    You can of course also use the same cpp-approach as for the first problem to generate slightly different function prologues and epilogues depending on what calling convention you need. 当然,您也可以使用与第一个问题相同的cpp方法,以根据所需的调用约定生成功能稍有不同的函数序言和结语。 However, this might be less maintainable. 但是,这可能难以维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM