Jos*_* Op 5 c gcc goto inline-assembly
某些使用goto限定符的扩展汇编语句无法使用 GCC 10.1.0 进行编译。具体来说,
int foo(int count)
{
asm goto ("dec %0; jb %l[stop]"
: "+r" (count)
:
:
: stop);
return count;
stop:
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(这是GCC 扩展 asm 文档中的一个示例)无法使用消息编译expected ‘:’ before string constant。删除"+r" (count)和dec %0允许它成功编译,但无论我在何时尝试在与 goto 标签相同的 asm 语句中提供输出操作数时,它都会以同样的方式出错。
您引用的当前开发GCC 文档似乎适用于 GCC 的最新主干分支,不适用于 GCC 的任何官方版本。GCC 的官方版本目前不支持asm goto任何输出或输入/输出限制。你可以在godbolt上看到这一点。最新的 trunk 可以工作,但 10.2 和 10.1 不行。修复方法是等待 GCC 的下一个主要版本(版本 11.x);下载并编译最新的主干版本;修改内联程序集,使其不依赖于任何输出或输出/输入约束。
直到最近,GCC 10.x 版本的文档还这样说:
asm goto 语句不能有输出。这是由于编译器的内部限制:控制传输指令不能有输出。如果汇编代码确实修改了任何内容,请使用“内存”破坏器强制优化器将所有寄存器值刷新到内存,并在 asm 语句之后根据需要重新加载它们。
可以在此URL找到正式版本的所有文档和当前开发文档的列表。当前的开发文档位于页面底部。根据经验,您应该查阅您的特定 GCC 版本的文档。我相信所有 10.x 版本的文档与 GCC 网页上最新的 10.x 版本的文档相同。
最新版本的 CLANG/LLVM (11.0+) 确实支持此功能,但这也是相对较新的添加。
asm goto 不允许输出操作数。
这是 GNU 的决定。在 c-parser.c 的函数 c_parser_for_statement 中,您可以找到:
/* For asm goto, we don't allow output operands, but reserve
the slot for a future extension that does allow them. */
Run Code Online (Sandbox Code Playgroud)
https://github.com/gcc-mirror/gcc/blob/releases/gcc-10/gcc/c/c-parser.c
然而,这种情况可能会改变,因为在主分支中该注释不再存在。