在x64 Visual Studio中内联汇编函数

use*_*597 6 c x86-64 masm visual-studio

我知道x64模式下的MSVC编译器不支持内联汇编代码片段,并且为了使用汇编代码,你必须在一些外部my_asm_funcs.asm文件中定义你的函数,如下所示:

my_asm_func PROC
    mov rax, rcx
    ret
my_asm_func ENDP
Run Code Online (Sandbox Code Playgroud)

然后在你的.c或.h文件中为这个函数定义一个标题:

int my_asm_func(int x);
Run Code Online (Sandbox Code Playgroud)

虽然该解决方案解决了许多问题,但我仍然有兴趣使汇编代码函数内联,换句话说 - 在编译之后我不想对my_asm_func进行任何"调用" ,我只是希望这个程序集被粘合进入我的最终编译代码.我尝试使用inline__forceinline关键字声明该函数,但似乎没有任何帮助.还有什么办法可以做我想要的吗?

Cod*_*ray 10

不,没有办法做你想做的事.

正如你所说,微软的编译器不支持x86-64目标的内联汇编.这会强制您在外部代码模块(*.asm)中定义汇编函数,使用MASM汇编它们,并将结果与​​单独编译的C/C++代码链接在一起.

所需的步骤分离意味着C/C++编译器无法内联汇编函数,因为它们在编译时不可见.

即使启用了链接时代码生成(LTCG),您的汇编模块也不会被内联,因为链接器根本不支持这一点.

绝对没有办法将汇编函数编写在一个单独的模块中直接内联到C或C++代码中.

这些inline__forceinline关键字无法做任何事情.事实上,没有编译器错误(或至少是警告),你无法使用它们.这些注释必须依赖于函数的定义(对于内联函数,它与其声明相同),但是您不能将它放在函数的定义上,因为它是在单独的*.asm文件中定义的.这些不是MASM关键字,因此尝试将它们添加到定义中必然会导致错误.并且将它们放在C头中的汇编函数的前向声明中同样是不成功的,因为那里没有内联代码 - 只是一个原型.

这就是Microsoft建议使用内在函数的原因.您可以直接在C或C++代码中使用它们,编译器将自动发出相应的汇编代码.这不仅可以实现所需的内联,而且内在函数甚至允许优化器运行,从而进一步改善结果.不,内在函数不会导致完美的代码,并且没有内在的东西,但它是你用微软的编译器做的最好的.

您唯一的另一种选择是坐下来使用各种C/C++代码排列,直到您让编译器生成所需的目标代码.如果内部函数不适用于您希望生成的指令,这可能会非常强大,但它确实需要花费大量时间来安装,并且您必须重新访问它以确保它继续执行您的操作在升级编译器版本时需要.

  • 您可以将函数标记为“naked”。这可能会避开函数调用并简单地跳转到独立的 asm 代码。另请参阅[如何在 x64 Visual C++ 中执行裸函数和内联汇编程序](/sf/ask/1864642881/)。 (3认同)
  • @jww `__declspec(naked)` 也不会导致函数被内联。事实上,如果我没记错的话,“裸”注释实际上会让优化器“更加”悲观。另外...这个问题是关于 x86-64 目标的,而 x86-64 目标甚至不存在 `__declspec(naked)` 。 (2认同)