Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is r() and double percent %% in GCC inline assembly language?

Example:

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 */
}
  • what is r(y)?
  • also why %% is used before eax? Generally single % is used right?
like image 572
brett Avatar asked Aug 28 '10 02:08

brett


People also ask

What is%% in assembly?

Special format strings In addition to the tokens described by the input, output, and goto operands, these tokens have special meanings in the assembler template: ' %% ' Outputs a single ' % ' into the assembler code. ' %= ' Outputs a number that is unique to each instance of the asm statement in the entire compilation.

What is r in inline assembly?

The lines with "r" or "=r" are operand constraints. The "=" means output operand. Essentially, this: :"=r"(y) :"r"(x) means that %0 (ie: the first operand) corresponds to y and is for output, and %1 (the second operand) corresponds to x.

What does R mean in assembly language?

Each operand is described by an operand constraint string followed by an expression in parentheses. The “r” in the operand constraint string indicates that the operand must be located in a register. The “=” indicates that the operand is written. Each output operand must have “=” in its constraint.

What is GCC in assembly?

The well-known GNU C/C++ Compiler (GCC), an optimizing 32-bit compiler at the heart of the GNU project, supports the x86 architecture quite well, and includes the ability to insert assembly code in C programs, in such a way that register allocation can be either specified or left to GCC.


1 Answers

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

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 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.

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.

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.

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;

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.

like image 185
Nils Pipenbrinck Avatar answered Oct 05 '22 13:10

Nils Pipenbrinck