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.