什么是R()和双百分号%%的GCC内联汇编语言? [英] What is r() and double percent %% in GCC inline assembly language?

查看:2754
本文介绍了什么是R()和双百分号%%的GCC内联汇编语言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如:

int main(void)
{
    int x = 10, y;

    asm ("movl %1, %%eax;"
        "movl %%eax, %0;"
        :"=r"(y)    /* y is output operand */
        :"r"(x)     /* x is input operand */
        :"%eax");   /* %eax is clobbered register */
}


  • 是什么 R(Y)

  • 也是为什么 %% 之前 EAX 使用吗?一般单使用权?

    • what is r(y)?
    • also why %% is used before eax? Generally single % is used right?
    • 推荐答案

      好吧,这是gcc内联汇编它非常强大,但是很难理解的。

      Okay, this is gcc inline assembler which very powerful but difficult to understand.

      首先,将%字符是一个特殊字符。它允许您定义的寄存器和数量的占位符(MOR稍后)。不幸的是,%也被用来作为(如%EAX),所以在GCC内联汇编你,如果你想命名寄存器使用两个百分比字符寄存器名称的一部分。

      First off, the % char is a special char. It lets you define register and number placeholders (mor on this later). Unfortunately the % is also used to as part of a register name (such as %EAX) so in gcc inline assembler you have to use two percent chars if you want to name a register.

      %0%1和%2(等..)是占位符的输入和输出操作数。这些列表中的后跟汇编字符串定义。
      在你的榜样%0变成y的一个占位符,1%,成为对于x的占位符。编译器将确保变量会在寄存器输入操作数asm- code之前得到执行,它将确保输出操作数将被写入到输出操作数列表中指定的变量。

      %0, %1 and %2 (ect..) are placeholder input and output operands. These are defined in the list followed by the assembler string. In your example %0 becomes a placeholder for y, and %1 becomes a placeholder for x. The compiler will make sure the variables will be in the registers for input operands before the asm-code gets executed, and it will make sure the output operand will get written to the variable specified in the output operand list.

      现在你应该得到一个想法是什么R(y)是:这是一个输入操作数保留为变量y寄存器并将其分配给占位符%1(因为它是内联汇编字符串后列出的第二个操作数)。
      还有很多其他的占位符类型。米,可以指定一个内存位置,如果我没有记错我可以用于数字常量。你会发现他们都在gcc文档中列出。

      Now you should get an idea what r(y) is: It is an input operand that reserves a register for the variable y and assigns it to the placeholder %1 (because it is the second operand listed after the inline assembler string). There are lots of other placeholder types. m lets you specify a memory location, and if I'm not mistaken i can be used for numeric constants. You'll find them all listed in the gcc documentation.

      再有就是撞名单。这份名单是很重要的!它列出了所有的寄存器,标志中,获取你的汇编code修改内存位置等(如EAX在你的例子)。如果你犯了这个错误,优化器将的的知道已被修改,这是非常有可能,你最终与code不起作用。

      Then there is the clobber list. This list is important! It lists all registers, flags, memory-locations ect that gets modified in your assembler code (such as the EAX in your example). If you get this wrong the optimizer will not know what has been modified and it is very likely that you end up with code that doesn't work.

      您例子是差不多的方式毫无意义。它只是加载值X到寄存器中,分配此寄存器EAX。随后EAX被存储到另一个寄存器,然后它以后将成为您的变量y。因此,所有它确实是一个简单的任务:

      Your example is by the way almost pointless. It just loads the value X into a register and assigns this register to EAX. Afterwards EAX gets stored into another register which will then later become your y variable. So all it does is a simple assignment:

      Y = X;

      一个最后一件事:如果您以前与英特尔式的汇编工作:你要倒读的论点。所有指令的源操作数是一个指令本身以下,而目标操作数是在逗号的权利的人。相比Intel的语法,这正是其他方式。

      A last thing: If you have worked with Intel-style assembler before: You have to read the arguments backwards. For all instructions the source operand is the one following the instruction itself, and the target operand is the one on the right of the comma. Compared to Intel syntax this is exactly the other way around.

      这篇关于什么是R()和双百分号%%的GCC内联汇编语言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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