在gcc内联汇编中,双百分号(%%)有什么作用?

UXk*_*EZ7 11 c x86 gcc

我遇到了一个代码如下:

asm volatile (
    # [...]
    "movl $1200, %%ecx;"
    # [...]
);
Run Code Online (Sandbox Code Playgroud)

我知道movl $1200, %ecxx86中有什么用.但我很困惑为什么有两个百分号.

Car*_*rum 10

GCC内联汇编使用%0,%1,%2等来表示输入和输出操作数.这意味着你需要使用两个%%来实现真正的寄存器.

请查看此howto以获取重要信息.


Cir*_*四事件 8

这取决于

  • 如果:字符串后面有一个冒号,那么它就是一个扩展的asm,并且会%%逃脱卡尔所提到的具有特殊意义的百分比.例:

    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);
    
    Run Code Online (Sandbox Code Playgroud)
  • 否则,它将是一个编译时错误,因为没有冒号它是一个基本的asm,它不支持变量约束,不需要或支持转义%1.例如:

    asm volatile ("movl $1200, %ecx;");
    
    Run Code Online (Sandbox Code Playgroud)

    工作得很好.

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