简体   繁体   中英

When to use a particular operand constraint in extended GCC inline assembly?

I'm having a hard time understanding when to use a particular input operand constraint over another in extended GCC inline assembly.

For example:

int x = 42;
asm("movl %0, %%eax;"
    : /* no outputs */
    : "r"(x)
    : "%eax");

I know that "r" tells the compiler to use a register hold the value of x , but when would it be more appropriate to use "g" or "m" ? Would using "m" break this code since I'm using a register destination; and would "g" be too "vague" of an operand constraint?

A large part of which constraint you use is whether the type it describes will work in the instructions you have. In mov %0, %%eax , you can put a register, a memory reference, or an immediate operand in place of %0 , and the assembler will accept it. So you can use g for the constraint.

If you had mov %0, 4(%%esp) , then you could not allow %0 to be a memory reference, because 4(%%esp) is a memory reference, and there is no form of the mov instruction that accepts two memory references. So you would need to use a constraint such as r to require %0 to be a register.

(Note that this code by itself is useless. As soon as the asm is done, the compiler is free to use %eax for anything it wishes, so there is no reason to expect that x will remain in the register. Moving something to %eax can be useful only in a sequence of instructions that uses %eax before allowing the compiler to have control again.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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