内联汇编:寄存器引用约定 [英] Inline assembly : register referencing conventions

查看:43
本文介绍了内联汇编:寄存器引用约定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In gcc inline assembly examples found on the net, I see register names being referenced sometimes with a single % and other times with two (i.e. %%). It's not clear when to use a single % and when to use %%. e.g. please see below example.

/* 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,kernel 2.6.18, gcc 4.7.2). 但是下面的单行代码

This example which uses %% prefix for EAX register compiles fine on my x86 machine (Linux RedHat 5.6(Tikanga 2.6.18-238.5.1.el5 x86_64, kernel 2.6.18, gcc 4.7.2). But the following single line code

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

产生以下错误.

a.c: Assembler messages:

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

有人能解释一下什么时候使用 % 以及什么时候使用 %% 吗?

Could someone please throw some light on when to use % and when to use %% ?

谢谢.

推荐答案

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

Inside the main body of the asm (ie. the part where the actual code goes), you use %1, %2, etc. to refer to the arguments to the inline-asm block. The inline-asm treats % as a special character for this purpose.

碰巧 x86 的 GNU 汇编器语法使用 % 作为 x86 寄存器名称的前缀(%eax、<代码>%ebx 等).但是,因为 inline-asm 为 % 分配了不同的含义,您必须将该块中的 % 加倍以对其进行转义.这就是为什么你会看到 movl %1, %%eax:第一个 %1 扩展为一个参数,%% 前面>%%eax 被替换为单个 %,从而在编译器的最终汇编输出中生成 %eax.

It so happens that the GNU assembler syntax for x86 also uses % as a prefix for the x86 register names (%eax, %ebx, etc.). But, because the inline-asm assigns different meaning to %, you have to double up the % in that block to escape it. That's why you see movl %1, %%eax: The first %1 expands to an argument, the %% in front of %%eax gets replaced with a single %, resulting in %eax in the final assembly output by the compiler.

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

In the other strings after the code block, % doesn't have this special meaning any more. That's why in the clobber list, for example, you only need to say %eax.

在您的第二个示例中,内联汇编器没有参数.没有 %1... 替换说明符,因此您无需将 % 加倍.

In your second example, the inline assembler has no arguments. There are no %1... substitution specifiers, and so you don't need to double up the %.

像泥一样清澈?

这篇关于内联汇编:寄存器引用约定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆