Embedded Assembly: Advanced Usages
3 parts: output, input , clobber.
output
The output consists of zero, one or more output operands, separated by commas. Each operand consists of a constraint(C_expression) pair. The output operand must be constrained by the = or + modifier (described below), and, optionally, by an additional % or & modifier.
input
The input consists of zero, one or more input operands, separated by commas. Each operand consists of a constraint(C_expression) pair.
clobbers
- r0 to r15
- General purpose registers
- cc
- Add cc to the list of clobbered registers if assembler instructions can alter the condition code.
- memory
-
Add memory to the clobber list if assembler instructions can change a memory location in an unpredictable fashion. The memory clobber ensures that the compiler does not to move the assembler instruction across other memory references and ensures that any data that is used after the completion of the assembly statement is valid.
However, the memory clobber can result in many unnecessary reloads, reducing the benefits of hardware prefetching. Thus, the memory clobber can impose a performance penalty and should be used with caution.
- modifier
- =
- Indicates that the operand is write-only for this instruction. The previous value is discarded and replaced by output data. See Example 3 for detailed usage information.
- +
- Indicates that the operand is both read and written by the instruction. See Example 4 for detailed usage information.
- &
- Indicates that the operand may be modified before the instruction is finished using the input operands; a register that is used as input should not be reused here.
- %
- Declares the instruction to be commutative for this operand and the following operand. This means that the order of this operand and the next may be swapped when generating the instruction. This modifier can be used on an input or output operand, but cannot be specified on the last operand.
- constraint
- a
- Use an address register (general purpose register except r0).
- d
- Use a data register that is an arbitrary general purpose register. This constraint is the same as the r constraint.
- g
- Use a memory or immediate operand.
- i
- Use an immediate integer or string literal operand.
- m
- Use a memory operand supported by the machine. You can use this constraint for operands of the form D(R), where D is a displacement and R is a register. See Example 5 for detailed usage information.
- n
- Use an immediate integer.
- o
- Use a memory operand that is offsetable.
- r
- Use a general register. See Example 3 for detailed usage information.
- s
- Use a string literal operand.
- v
- Use a vector register.
- 0, 1, …8, 9
- A matching constraint. Allocate the same register in output as in the corresponding input.
- I, J, K
- Integer constant values
- Q, R, S, T
- Memory operands. They are treated the same as constraint m.
- C_expression
The C_expression is a C or C++ expression whose value is used as the operand for the asm instruction. Output operands must be modifiable lvalues. The C_expression must be consistent with the constraint specified on it. For example, if i is specified, the operand must be an integer constant number.
int main(){ int sum = 0, one=1, two = 2; __asm ("AR %[result], %[first]\n" "AR %[result], %[second]\n" :[result] "+r"(sum) :[first] "r"(one), [second] "r"(two) ); return sum == 3 ? 0 : 1; } #include <stdio.h> int main() { int res = 25; int newRes = 55; asm("LR %0,%1\n" :"=r"(res) :"r"(newRes) ); return res; } #include <stdio.h> int main() { int res = 25; asm(" AHI %0,%1\n" :"+r"(res) : "K"(30) ); return res; } int main() { int val=40, dest; asm(" ST %1,%0\n" :"=m"(dest) :"r"(val) ); return 40 == dest ? 55 :66; }
difference between using '+' and '=' with output oprand:


Sometimes multiple asm in one embedded asm, the output register might also be allocate as input register. So as input register, it is updated before #APP, and modified by certain asm in the multi-embedded asm. If this register shall be used as input register after that certain asm, we cannot get that pre-updated value as input register. So to avoid that circumstance, use '&' as modifier for the output register to prevent this register to be used as input register.
浙公网安备 33010602011771号