首页 > 解决方案 > 带有 goto 的扩展 asm,包括来自 gcc 文档的示例,无法编译

问题描述

一些使用限定符的扩展汇编语句goto无法用 GCC 10.1.0 编译。具体来说,

int foo(int count)
{
  asm goto ("dec %0; jb %l[stop]"
            : "+r" (count)
            :
            :
            : stop);
  return count;
stop:
  return 0;
}

(这是GCC 扩展 asm 文档中的一个示例)无法使用消息进行编译expected ‘:’ before string constant。删除"+r" (count)dec %0允许它成功编译,但无论何时在与 goto 标签相同的 asm 语句中提供输出操作数时我尝试什么,它都会以同样的方式出错。

标签: cgccinline-assemblygoto

解决方案


您引用的当前开发GCC 文档似乎适用于 GCC 的最新主干分支,不适用于 GCC 的任何官方版本。到目前为止,GCC 的正式版本不支持asm goto任何输出或输入/输出约束。你可以在Godbolt上看到这个。最新的主干有效,但 10.2 和 10.1 无效。修复方法是等待 GCC 的下一个主要版本(版本 11.x);下载并编译最新的主干版本;修改您的内联程序集,使其不依赖于任何输出或输出/输入约束。

直到最近,GCC 10.x 版的文档都这样说:

asm goto 语句不能有输出。这是由于编译器的内部限制:控制转移指令不能有输出。如果汇编程序代码确实修改了任何内容,请使用“内存”破坏程序强制优化器将所有寄存器值刷新到内存,并在 asm 语句之后重新加载它们(如有必要)。

可以在此URL找到正式版本的所有文档和当前开发文档的列表。当前的开发文档位于页面底部。经验法则是您应该查阅特定 GCC 版本的文档。我相信所有 10.x 版本的文档都与 GCC 网页上最新的 10.x 版本的文档相同。

最新版本的 CLANG/LLVM (11.0+) 确实支持此功能,但这也是相对较新的添加。


推荐阅读