美文网首页
Visual Studio 不支持x64 vc中内联汇编的原因

Visual Studio 不支持x64 vc中内联汇编的原因

作者: onedam | 来源:发表于2021-10-21 12:11 被阅读0次

    Visual Studio目前只支持32位(x86)的内联汇编,而不支持64位(x64)下的内联汇编,在x64下编译的话,
    会报错 “使用了非标准扩展: 不支持在此结构上使用“__asm”关键字”。
    !!! linux 下gcc 一直支持 内联汇编.
    vc 下 需要单独写到asm文件中. 然后在c++ 中调用 . 内联asm对优化形成较大的阻扰

    微软 建议使用 Compiler intrinsics (编译器内部的函数, 这样编译器完全可以控制了. 内部优雅 filter 掉 优化障碍)
    大多数函数都包含在库中,但也有一些函数是在编译器中生成的(即内部函数)。 这些被称为内联函数或内部函数。

    如果一个函数是内部函数,在通常会采用内联方式插入该函数的代码,从而避免函数调用的开销并可发出该函数的高效率计算机指令。 内部函数通常比等效的内联程序集速度更快,因为优化程序拥有众多内部函数行为方式的内置知识,因此可以优化使用内联程序集无法优化的内容。 此外,优化程序还可以采用不同的方式扩展内部函数、对齐缓冲区或根据上下文和调用自变量进行其他方面的调整。

    例如 这个
    __outbyte
    生成 out 指令,该指令发送由指定的 i/o 端口指定的1个字节 Data Port 。

    void __outbyte(
    unsigned short Port,
    unsigned char Data
    );

    __readcr0 读取 CR0 寄存器并返回其值。

    unsigned long __readcr0(void); /* X86 /
    unsigned __int64 __readcr0(void); /
    X64 */

    https://docs.microsoft.com/zh-cn/cpp/intrinsics/stosb?view=msvc-160
    生成存储字符串指令 rep stosb () 。
    void __stosb(
    unsigned char* Destination,
    unsigned char Data,
    size_t Count
    );

    为什么 VC 不允许 x64 内联汇编? https://www.zhihu.com/question/23236719
    Visual C++ 至今都禁止 x64 编译模式下使用 __asm 关键字内联汇编。
    每次要用汇编的时候都得另外开一个 ASM 文件写,然后 call 过去。
    始终不能理解微软为何要禁止这一特性。

    知不知道写代码优化器的看到内联汇编就会头大?很多优化和内联汇编不兼容。
    x86的是必须向后兼容没办法,x64的没有传统代码拖后腿的就可以砍掉了。
    要写汇编自己开ASM文件写去不要放在C++文件里妨碍优化器工作。
    作为用户来说,为了几句汇编就把优化器提供的优化丢掉是捡了芝麻丢了西瓜。

    https://www.zhihu.com/question/28357966

    markliPRC:
    虽然我也不知道为啥取消了,但可以告诉你一个替代方法。
    把以前的内联汇编用masm写成函数,放在asm文件里。

    Giving up the support of the inline assembler code (through the key word __asm) when compiling applications for the 64-bit platforms Intel 64 and IA-64 is most probably related to the wish of the Microsoft company to simplify the optimizer's work and development of new versions of the compiler for Visual C++. Inline assembler code limits portability of software being developed while optimization by its means is rarely reasonable nowadays since the compiler creates rather efficient code most times.When the functionality you need cannot be implemented by means of the C++ code, use intrinsic functions to replace assembler fragments or link external asm-files to the project.

    https://docs.microsoft.com/zh-cn/cpp/intrinsics/compiler-intrinsics?view=msvc-160
    https://docs.microsoft.com/en-us/cpp/intrinsics/compiler-intrinsics?view=msvc-160

    新建一个文件,在文件中定义一个汇编函数。
    .code
    
    ; add_one 函数返回参数加 1 的值
    add_one proc
        mov eax, ecx
        add eax, 1
        ret
    add_one endp
    
    end
    

    在项目中声明这个函数的原型:

    extern "C" int add_one(int);

    这样写的时候 要注意 abi
    非常重要的一个概念 abi . 这样可以 直接调用二进制的 函数. (以前对api熟悉) 应用程序接口(Application Programming Interface,API

    ABI(Application Binary Interface):应用程序二进制接口,描述了应用程序和操作系统之间,一个应用和它的库之间,
    或者应用的组成部分之间的低接口。ABI涵盖了各种细节,如:
    数据类型的大小、布局和对齐;
    调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;
    哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
    系统调用的编码和一个应用如何向操作系统进行系统调用;
    以及在一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等。
    https://zhuanlan.zhihu.com/p/386106883

    Linux下,GCC支持x86-32/64的内联汇编。Windows下,Visual Stdio支持x86-32的内联汇编,但不支持x64的内联汇编(至少到Visual Studio 2010是这样),而是提供了一些Intrinsics(一种类似于内联函数的东西)。MSDN给出了这些intrinsics的列表:http://msdn.microsoft.com/en-us/library/26td21ds.aspx

    这些intrinsics可以让我们使用cpuid和rdstc这类底层特性,但终归有限的intrinsics是无法满足人民日益增长的开发需要的,于是我们需要能更方便写汇编代码的方法。这里讨论三种方法:

    相关文章

      网友评论

          本文标题:Visual Studio 不支持x64 vc中内联汇编的原因

          本文链接:https://www.haomeiwen.com/subject/rthdfktx.html