12

我遇到了一个看起来像这样的代码:

asm volatile (
    # [...]
    "movl $1200, %%ecx;"
    # [...]
);

我知道movl $1200, %ecx在 x86 中做了什么。但我对为什么有两个百分号感到困惑。

4

3 回答 3

12

GCC 内联汇编使用 %0、%1、%2 等来引用输入和输出操作数。这意味着您需要将两个 %% 用于实际寄存器。

查看此操作指南以获取重要信息。

于 2013-02-07T07:16:17.053 回答
8

这取决于

  • 如果字符串后面有一个冒号:,那么它是一个扩展的 asm,并转义了Carl 提到的%%可能具有特殊含义的百分比。例子:

    uint32_t in = 1;
    uint32_t out = 0;
    asm volatile (
        "movl %1, %%eax;"
        "inc %%eax;"
        "movl %%eax, %0"
        : "=m" (out) /* Outputs. '=' means written to. */
        : "m" (in)   /* Inputs. No '='. */
        : "%eax"
    );
    assert(out == in + 1);
    
  • 否则,这将是一个编译时错误,因为没有冒号它是一个基本的 asm,它不支持变量约束并且不需要或支持转义%1。例如:

    asm volatile ("movl $1200, %ecx;");
    

    工作得很好。

扩展 asm 更常用,因为它更强大。

于 2015-07-29T21:07:54.207 回答
0

这有助于 GCC 区分操作数和寄存器。操作数有一个 % 作为前缀。'%%' 总是与寄存器一起使用。

于 2013-10-24T10:22:18.877 回答