在__asm中插入注释会导致 C2400 错误 (VS2012)
Inserting a comment in __asm results in C2400 error (VS2012)
我试图在VS 2012中检查一些代码的编译汇编程序。我添加了两行(在我的代码之前和之后(:
__asm ; it begins here!
// My code
__asm ; it ends here!
但是,VS不喜欢这样。我得到了
错误C2400:"操作码"中的内联汇编程序语法错误;发现"错误令牌"
所以我添加了一个NOP
,我不想:
__asm NOP ; Comment!
效果很好。我的问题是双重的。
- 为什么 VS 不允许我添加程序集注释?
- 有没有其他方法可以在不添加指令的情况下添加程序集注释,包括
NOP
?
它不起作用的原因是__asm
是一个关键字,就像int
是一个关键字一样,它不能单独出现,必须遵循正确的语法。以以下一段代码为例:
int main()
{
int // here's a comment, but it's ignored by the compiler
return 0;
}
以下代码将失败并出现编译错误,更具体地说,在VS2012中,您会得到error C2143: syntax error : missing ';' before 'return'
。这是一个明显的错误,因为我们没有结束分号来表示指令结束;添加分号,它编译得很好,因为我们没有违反 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;
}
除了这里我们得到错误error C2400: inline assembler syntax error in 'opcode'; found 'constant'
,因为它将 __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;
}
所以这回答了你的第一个问题:Why didn't VS allow me to add an assembly comment?
..因为这是一个语法错误。
现在回答第二个问题:Is there a different way to add an assembly comment without adding an instruction, including NOP?
直接,不,没有,但间接,是有。值得注意的是,__asm
关键字在程序中编译为内联程序集,因此注释将从编译的程序集中删除,就好像它是标准的 C/C++ 注释一样,因此尝试通过该方法在程序集中"强制"注释是不必要的,相反,您可以使用 /FAs
编译器标志,它将生成与源代码混合的程序集(机器代码(, 例:
给定以下(非常简单的(代码:
int main()
{
// here's a normal comment
__asm { ; here's an asm comment and empty block
} // here's another normal comment
return 0;
}
使用 /FAs
编译器标志进行编译时,生成的file.asm
具有以下输出:
; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.31101.0
TITLE C:testfile.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC _main
; Function compile flags: /Odtp
; File c:testfile.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++ 样式注释以及__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;
}
希望能有所帮助。
编辑:
应该注意的是,以下代码也可以编译而没有错误,我不是 100% 确定为什么:
int main()
{
__asm
__asm ; comment
// also just doing it on a single line works too: __asm __asm
return 0;
}
使用单个__asm ; comment
编译此代码会产生编译错误,但两者的编译效果很好;向上述代码添加指令并检查.asm
输出表明,对于它前面的任何其他程序集命令,第二个__asm
将被忽略。所以我不是 100% 确定这是一个解析错误还是 __asm
关键字语法的一部分,因为没有关于此行为的文档。
在 Linux 上,g++ 接受这一点:
__asm(";myComment");
和输出,当您运行g++ -S -O3 filename.cpp
:
# 5 "filename.cpp" 1
;myComment
但是,clang++ 不喜欢它,并在您运行 clang++ -S -O3 filename.cpp
时
filename.cpp:5:9: error: invalid instruction mnemonic 'myComment'
__asm(";myComment");
^
<inline asm>:1:3: note: instantiated into assembly here
;myComment
^~~~~~~~~
<小时 />但是,我能够让 g++ 和 clang++ 都接受:
__asm("//myComment");
对于两个编译器,它输出与上述程序集输出中相同的注释。
<小时 />当我无法在互联网上的其他任何地方找到它时,是什么让我明白了这一点,而是从这里阅读:
Microsoft特定
__asm块中的指令可以使用汇编语言注释:
C++
__asm mov ax, offset buff ; Load address of buff
由于 C 宏扩展为单个逻辑行,因此请避免使用宏中的汇编语言注释。(请参阅将__asm块定义为 C宏。__asm块还可以包含 C 样式注释;了解更多信息,请参阅在__asm块中使用 C 或 C++。
结束 Microsoft 特定
然后,此页面链接到此处和此处。这些提供了有关此事的更多信息。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C2400 内联汇编程序语法错误,与 2015 年
- 在__asm中插入注释会导致 C2400 错误 (VS2012)