Inline assembly statements
Under extended language levels, the compiler provides support for embedded assembly code fragments among C and C++ source statements.
This extension has been implemented for use in general system programming code, and in the operating system kernel and device drivers, which were originally developed with GNU C.
The keyword asm
stands for assembly code. When strict language levels are used
in compilation, the C compiler treats asm
as a regular identifier and reserves
__asm
and __asm__
as keywords.
The C++ compiler always recognizes the asm
,
__asm
, and __asm__
keywords.
- volatile
- The qualifier
volatile
instructs the compiler to perform only minimal optimizations on the assembly block. The compiler cannot move any instructions across the implicit fences surrounding the assembly block. See Example 1 for detailed usage information. - code_format_string
- The code_format_string is the source text of the
asm
instructions and is a string literal similar to aprintf
format specifier.Operands are referred to in the
%integer
format, where integer refers to the sequential number of the input or output operand. See Example 1 for detailed usage information.To increase readability, each operand can be given a symbolic name enclosed in brackets. In the assembler code section, you can refer to each operand in the
%[symbolic_name]
format, where the symbolic_name is referenced in the operand list. You can use any name, including existing C or C++ symbols, because the symbolic names have no relation to any C or C++ identifiers. However, no two operands in the same assembly statement can use the same symbolic name. See Example 2 for detailed usage information. - 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
-
clobbers is a comma-separated list of register names enclosed in double quotes. If an
asm
instruction updates registers that are not listed in the input or output of theasm
statement, the registers must be listed as clobbered registers. The following register names are valid :- r0 to r31
- General purpose registers
- f0 to f31
- Floating-point registers
- lr
- Link register
- ctr
- Loop count, decrement and branching register
- fpscr
- Floating-point status and control register
- xer
- Fixed-point exception register
- cr0 to cr7
- Condition registers. Example 3 shows a typical use of condition registers in the clobbers.
- v0 to v31
- Vector registers (on selected processors only)
In addition to the register names,cc
andmemory
can also be used in the list of clobbered registers. The usage information ofcc
andmemory
is listed as follows:- cc
- Add
cc
to the list of clobbered registers if assembler instructions can altercr0
. - memory
-
Add
memory
to the clobber list if assembler instructions can change a memory location in an unpredictable fashion. Thememory
clobber ensures that the compiler does not 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, thememory
clobber can impose a performance penalty and should be used with caution. See Example 4 and Example 1 for the detailed usage information.
- modifier
-
The modifier can be one of the following operators:
- =
- Indicates that the operand is write-only for this instruction. The previous value is discarded and replaced by output data.
- +
- Indicates that the operand is both read and written by the instruction. See Example 5 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. See Example 6 for detailed usage information.
- constraint
-
The constraint is a string literal that describes the kind of operand that is permitted, one character per constraint. The following constraints are supported:
- a
- Use an address operand that is an indexed or indirect address from a register.
- b
- Use a general register other than zero. Some instructions treat the designation of register
0 specially, and do not behave as expected if the compiler chooses
r0
. For these instructions, the designation ofr0
does not mean thatr0
is used. Instead, it means that the literal value 0 is specified. See Example 7 for detailed usage information. - c
- Use the CTR register.
- d
- Use a floating-point register.
- f
- Use a floating-point register. See Example 6 for detailed usage information.
- h
- Use the CTR or LINK register.
- l
- Use the link register, lr.
- m
- Use a memory operand supported by the machine. You can use this constraint for operands of
the form
D(R)
, whereD
is a displacement andR
is a register. See Example 8 for detailed usage information. - v
- Use a vector register.
- wa
- Use any VSX register or paired VSX register
- x
- Use a condition register field 0, cr0.
- y
- Use any condition register field, cr0, cr1...cr7.
- I, J, K, L
- Constant values. Fold the expression in the operand and substitute the value into the
%
specifier. These constraints specify a maximum value for the operand, as follows:- I — signed 16-bit
- J — unsigned 16-bit shifted left 16 bits
- K — unsigned 16-bit constant
- L — signed 16-bit shifted left 16 bits
- Q
- Use a memory operand that is an offset from a register.
- R
- Use an AIX TOC entry.
- Z
- Use a memory operand that is accessed with an indexed or indirect addressing from a register.
- 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, ifi
is specified, the operand must be an integer constant number.