asm statement can be used to embed code written in assembly
inside a C or XC function. For example, the add instruction can be
written as follows:
asm("add %0, %1, %2" : "=r"(result) : "r"(a), "r"(b));
Colons separate the assembler template, the output operands and the
input operands. Commas separate operands within a group. 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 “
=” in the operand
constraint string indicates that the operand is written.
Each output operand expression must be an lvalue and must have “
in its constraint.
The location of an operand may be referred to in the assembler template
using an escape sequence of the form
num is the
operand number. The escape sequence “
%=” can be used to emit a
number that is unique to each expansion of an
asm statement. This
can be useful for making local labels. To produce a literal “
must write “
If code overwrites specific registers this can be described by using a third colon after the input operands, followed by the names of the clobbered registers as a comma-separated list of strings. For example:
asm ("get r11, id\n\tmov %0, r11" : "=r"(result) : /* no inputs */ : "r11");
The compiler ensures none of input or output operands are placed in clobbered registers.
asm statement has output operands, the compiler assumes the statement
has no side effects apart from writing to the output operands. The compiler may
asm statement if the values written by the
asm statement are
unused. To mark an
asm statement as having side effects add the
volatile keyword after
asm. For example:
asm volatile("in %0, res[%1]" : "=r"(result) : "r"(lock));
asm statement accesses memory, add “
memory” to the list of
clobber registers. For example:
asm volatile("stw %0, dp" : /* no outputs */ : "r"(value));
This prevents the compiler caching memory values in registers around the
The earlyclobber constraint modifier “
&” can be used to specify that
an output operand is modified before all input operands are consumed.
This prevents the compiler from placing the operand in the same register
as any of the input operands. For example:
asm("or %0, %1, %2\n" "or %0, %0, %3\n" : "=&r"(result) : "r"(a), "r"(b), "r"(c));
Jumps from one
asm statement to another are not supported.
statements must not be used to modify the event enabled status of any resource.
An input operand can be tied to an output operand by specifying the number of the output operand in the input operand’s constraint. For example:
- asm(“zext %0, 8n”
: “=r”(result) : “0”(x));
Operands that are tied together will be allocated to the same register.