Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在asm中插入注释会导致C2400错误(VS2012)_C++_Visual Studio_Assembly_Visual C++ - Fatal编程技术网

C++ 在asm中插入注释会导致C2400错误(VS2012)

C++ 在asm中插入注释会导致C2400错误(VS2012),c++,visual-studio,assembly,visual-c++,C++,Visual Studio,Assembly,Visual C++,我试图在VS2012中检查一些代码的编译汇编程序。我添加了两行代码(代码前后): 然而,VS不喜欢这样。我得到 错误C2400:“操作码”中的内联汇编程序语法错误;发现“坏令牌” 所以我添加了一个NOP,我不想: __asm NOP ; Comment! 效果很好。我的问题有两方面 为什么VS不允许我添加程序集注释 是否有其他方法可以在不添加指令的情况下添加程序集注释,包括NOP 它不起作用的原因是它是一个关键字,就像int是一个关键字一样,它不能单独出现,必须遵循正确的语法。以以下代码位为例

我试图在VS2012中检查一些代码的编译汇编程序。我添加了两行代码(代码前后):

然而,VS不喜欢这样。我得到

错误C2400:“操作码”中的内联汇编程序语法错误;发现“坏令牌”

所以我添加了一个
NOP
,我不想:

__asm NOP ; Comment!
效果很好。我的问题有两方面

  • 为什么VS不允许我添加程序集注释
  • 是否有其他方法可以在不添加指令的情况下添加程序集注释,包括
    NOP

  • 它不起作用的原因是它是一个关键字,就像
    int
    是一个关键字一样,它不能单独出现,必须遵循正确的语法。以以下代码位为例:

    int main()
    {
        int      // here's a comment, but it's ignored by the compiler
        return 0;
    }
    
    以下代码将因编译错误而失败,更具体地说,在VS2012中,您会得到
    错误C2143:语法错误:缺少“;”在“返回”之前
    。这是一个明显的错误,因为我们没有结束分号来表示指令的结束;添加半冒号,它编译得很好,因为我们不服从C(或C++在这种情况下)的语法:

    int main()
    {
        int      // here's a comment, but it's ignored by the compiler
        ; // white space and comments are ignored by the compiler
        return 0;
    }
    
    以下代码也是如此:

    int main()
    {
        __asm ; here's a comment but it's ignored
    
        return 0;
    }
    
    除了这里,我们得到的错误是:操作码中的内联汇编程序语法错误;找到“constant”,因为它将
    \u asm
    关键字之后的所有内容都视为汇编指令,注释被正确地忽略。。因此,以下代码将起作用:

    int main()
    {
        __asm ; here's a comment but it's ignored
        NOP ; white space and comments are ignored by the compiler
    
        __asm {; here's an __asm 'block'
        } // outside of __asm block so only C style comments work
        return 0;
    }
    
    这就回答了您的第一个问题:
    为什么VS不允许我添加程序集注释?
    。。因为这是一个语法错误

    现在来看第二个问题:
    是否有其他方法可以在不添加指令(包括NOP)的情况下添加程序集注释?

    直接地,不,没有,但间接地,有。值得注意的是,
    \uu asm
    关键字被编译到程序中的内联程序集中,因此注释将从编译的程序集中删除,就像它是标准的C/C++注释一样,因此不需要通过该方法在程序集中“强制”注释,您可以使用编译器标志,它将生成与源代码混合的程序集(机器代码),例如:

    给出以下(非常简单)代码:

    使用
    /FAs
    编译器标志编译时,生成的
    文件.asm
    中有以下输出:

    ; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.31101.0 
    
        TITLE   C:\test\file.cpp
        .686P
        .XMM
        include listing.inc
        .model  flat
    
    INCLUDELIB LIBCMT
    INCLUDELIB OLDNAMES
    
    PUBLIC  _main
    ; Function compile flags: /Odtp
    ; File c:\test\file.cpp
    _TEXT   SEGMENT
    _main   PROC
    
    ; 2    :     {
    
        push    ebp
        mov ebp, esp
    
    ; 3    :         // here's a normal comment
    ; 4    :         __asm { ; here's an asm comment and empty block
    ; 5    :         } // here's another normal comment
    ; 6    :         return 0;
    
        xor eax, eax
    
    ; 7    :     }
    
        pop ebp
        ret 0
    _main   ENDP
    _TEXT   ENDS
    END
    
    注意它是如何包含源代码和注释的。如果这段代码做得更多,您将看到更多的程序集以及与之相关的源代码

    如果要在内联程序集本身中添加注释,则可以使用普通C/C++样式的注释以及
    \u asm
    块本身中的程序集注释:

    int main()
    {
        // here's a C comment
        __asm { ; here's an asm comment
            // some other comments
            NOP ; asm type comment
            NOP // C style comment
        } // here's another comment
        return 0;
    }
    
    希望这能有所帮助

    编辑:

    需要注意的是,以下代码也可以无误编译,我不确定原因是什么:

    int main()
    {
        __asm
        __asm ; comment
        // also just doing it on a single line works too: __asm __asm
        return 0;
    }
    

    使用单个
    \uu asm编译此代码;comment
    给出了编译错误,但使用这两种方法编译都很好;向上述代码中添加指令并检查
    .asm
    输出表明,第二个
    \uu asm
    之前的任何其他汇编命令都会被忽略。因此,我不能100%确定这是一个解析错误还是asm关键字语法的一部分,因为没有关于此行为的文档。

    在Linux上,g++接受这一点:

    \uu asm(“myComment”);
    
    和输出,当您运行
    g++-S-O3 filename.cpp

    # 5 "filename.cpp" 1
        ;myComment
    
    filename.cpp:5:9: error: invalid instruction mnemonic 'myComment'
      __asm(";myComment");
            ^
    <inline asm>:1:3: note: instantiated into assembly here
            ;myComment
             ^~~~~~~~~
    
    但是,当您运行
    clang++-S-O3 filename.cpp时,clang++不喜欢它,并且对此表示不满:

    # 5 "filename.cpp" 1
        ;myComment
    
    filename.cpp:5:9: error: invalid instruction mnemonic 'myComment'
      __asm(";myComment");
            ^
    <inline asm>:1:3: note: instantiated into assembly here
            ;myComment
             ^~~~~~~~~
    
    对于两个编译器,它输出与上述程序集输出中相同的注释


    当我在互联网上其他任何地方都找不到它时,让我陷入这一困境的是:

    特定于Microsoft的

    asm块中的指令可以使用汇编语言注释:

    C++

    \u asm mov ax,offset buff;buff的加载地址
    
    由于C宏扩展到单个逻辑行,因此避免使用 宏中的汇编语言注释。(请参见将asm块定义为C 宏。)asm块也可以包含C样式的注释;更多 信息,参见C或C++中的.ASM块。 结束特定于Microsoft的操作


    此页面然后链接到和。这些提供了更多关于这件事的信息。

    \uu asm{
    /
    //Comment
    /
    }
    也不起作用吗?当你把注释放在自己的行上,或者只有在< C++ >代码> >代码>块中没有任何指令时,这总是发生吗?你的建议不起作用(我认为评论和<代码> } /代码>被解析为C++注释)。正如我在问题中所写的,
    \uasm NOP;评论工作。问题就在没有指令的时候。我的注释中代码格式块之间的斜杠代表换行符,所以它不是全部放在一行上。但也许你明白了。哦,你希望这些注释出现在编译器的汇编输出中?如果你想让注释出现在程序集中,不管你使用什么格式的注释,程序集风格还是C/C++风格。无论哪种方式,注释都不会出现在生成的程序集中,除非您使用/FAs选项,并且在这种情况下,整个源代码行在程序集中显示为注释。x86 GNU汇编程序语法的注释字符为
    #
    。分号(
    )分隔两条指令或指令,如
    dec%ecx;jnz.Lloop
    。clang有一个内置的汇编程序,它要求asm对其进行有效编译,而GCC只对模板进行文本替换,不关心asm输出中的文本-尝试在不使用
    -S
    的情况下构建。(或在锁紧螺栓上,使用“二进制”模式完全组装