繁体   English   中英

内联汇编:注册引用约定

[英]Inline assembly : register referencing conventions

在网上找到的gcc内联汇编示例中,我看到有时使用单个%引用寄存器名称,有时使用两个引用(即%% )。 目前尚不清楚何时使用单个%以及何时使用%% 例如,请看下面的例子。

/* Do b = a */

  int a=10, b;

  asm ("movl %1, %%eax;\n"
       "movl %%eax, %0;"
       : "=r" (b)        /* output */
       : "r" (a)         /* input */
       : "%eax"          /* clobbered register */
       );

这个在EAX寄存器上使用%%前缀的例子在我的x86机器上编译得很好(Linux RedHat 5.6(Tikanga 2.6.18-238.5.1.el5 x86_64,内核2.6.18,gcc 4.7.2)。但是下面的单行代码

asm ("movl %%ecx, %%eax");

产生以下错误。

a.c: Assembler messages:

a.c:14: Error: bad register name `%%ecx'

有人可以请问什么时候使用%以及何时使用%%

谢谢。

asm的主体内部(即实际代码所在的部分),使用%1%2等来引用inline-asm块的参数。 为此目的,inline-asm将%视为特殊字符。

碰巧x86的GNU汇编语法使用%作为x86寄存器名称的前缀( %eax%ebx等)。 但是,因为inline-asm为%赋予不同的含义,所以你必须将该块中的%加倍以逃避它。 这就是为什么你看到movl %1, %%eax :第一%1扩展到一个参数, %%前面%%eax获取与单取代% ,致使%eax在编译器的最终输出组件。

在代码块之后的其他字符串中, %不再具有此特殊含义。 这就是为什么在clobber列表中,例如,你只需要说%eax

在第二个示例中,内联汇编程序没有参数。 没有%1 ...替换说明符,因此您不需要将%加倍。

像泥一样清楚?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM