【问题标题】:Expected ')' before token inline assembly error令牌内联汇编错误之前应为“)”
【发布时间】:2021-06-14 16:26:49
【问题描述】:

我想学习一些内联汇编编程,但是我的第一个 cod sn-p 不起作用。我有一个字符串,我想将字符串的值分配给 rsi 寄存器。

这是我的代码:

    string s = "Hello world";
    const char *ystr = s.c_str();
    asm("mov %1,%%rsi"
    :"S"(ystr)
    :"%rsi" //clobbered register
);

    return 0;

它在令牌之前给了我错误:Expected ')'。任何帮助表示赞赏。

【问题讨论】:

  • 你真的在代码中写了;clobbered register吗?
  • 是的,但我写的是评论。
  • C++ 中的注释以// 开头,而不是;
  • 您还有其他几个问题:(1) 扩展 asm 操作数从 0 开始编号,而不是 1 (2) 指定 S 约束已经导致编译器将值加载到 rsi , 所以mov 是不必要的 (3) 你不能破坏操作数被限制加载到的同一个寄存器。
  • (4) 第一个冒号后面的操作数应该是输出,而不是输入; "mov %0, %%rsi""S" 之间需要两个冒号。

标签: c++ inline-assembly


【解决方案1】:

您遗漏了 : 来分隔空输出部分。所以"S"(ystr)是输出部分的输入操作数,"%rsi"是输入部分,而不是clobbers。

但作为输入,它缺少 "constraint"(var_name) 语法的 (var_name) 部分。所以这是一个语法错误,也是一个语义错误。这是错误<source>:9:5: error: expected '(' before ')' token 的直接来源。 https://godbolt.org/z/97aTdjE8K


正如 Nate 指出的那样,您还有其他几个错误,例如尝试使用 "S" 强制输入选择 RSI。

   char *output;   // could be a dummy var if you don't actually need it.
   asm("mov %1, %0"
     : "=r" (output)     /// compiler picks a reg for you to write to.
    :"S"(ystr)           // force RSI input
    :   // no clobbers
   );

请注意,这不会告诉编译器您读取或写入指向的内存,所以它只对这样的东西是安全的,它复制地址但不期望读取或写入指向的数据。

也相关:

【讨论】:

    【解决方案2】:

    一般来说,当在 x86 上使用 gcc 内联 asm 时,您希望避免使用 mov 指令,并希望避免在 asm 代码中显式寄存器 - 只需使用寄存器约束在适当的寄存器中获取内容。因此,对于您的示例,将字符串指针放入 rsi 寄存器中,您只需要:

    asm volatile("; ystr wil be in %rsi here"
                :  // no output contraints
                : "S"(ystr)  // input constraint
                :  // no clobber needed
                );
    

    请注意,这里没有实际的 asm 代码输出——只是一个注释。输入约束足以在出现此点之前将操作数放入所需的寄存器。是的,rsi 之后很可能会用于其他用途,但这是意料之中的——寄存器约束仅涵盖 asm 文本的输入和输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 2016-09-06
      • 2017-05-30
      相关资源
      最近更新 更多