C++ 在asm中插入注释会导致C2400错误(VS2012)
我试图在VS2012中检查一些代码的编译汇编程序。我添加了两行代码(代码前后): 然而,VS不喜欢这样。我得到 错误C2400:“操作码”中的内联汇编程序语法错误;发现“坏令牌” 所以我添加了一个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是一个关键字一样,它不能单独出现,必须遵循正确的语法。以以下代码位为例
NOP
,我不想:
__asm NOP ; Comment!
效果很好。我的问题有两方面
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
的情况下构建。(或在锁紧螺栓上,使用“二进制”模式完全组装