在x64 Visual Studio中内联汇编函数

时间:2016-12-18 11:57:46

标签: c visual-studio x86-64 masm

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

my_asm_func PROC
    mov rax, rcx
    ret
my_asm_func ENDP

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

int my_asm_func(int x);

尽管该解决方案解决了许多问题,但我仍然有兴趣将汇编代码函数设置为内联,换句话说 - 在编译之后我不希望对 my_asm_func 进行任何“调用”,我只是希望将这个程序集粘贴到我最终编译的代码中。我尝试使用内联 __ forceinline 关键字声明该功能,但似乎没有任何帮助。还有什么办法可以做我想要的吗?

3 个答案:

答案 0 :(得分:10)

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

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

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

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

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

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

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

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

答案 1 :(得分:1)

由于标题提到的是Visual Studio而不是MSVC,因此我建议通过Visual Studio安装程序安装Clang。它可以像MSVC一样使用,而无需配置自定义生成任务或任何其他内容,它支持以Intel语法和变量作为操作数的内联汇编。

只需从项目属性页的Platform Toolset部分的General中选择“ LLVM(clang-cl)”,就可以了。

答案 2 :(得分:0)

是的,你可以。将您的过程组装为 shellcode 并提取字节,然后将其包含在代码中具有 RWX 内存保护的缓冲区中。调用代码。