Inline assembly statements (C only) (IBM extension)

Under extended language levels, the compiler provides full 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 recognizes and ignores the keyword asm in a declaration. The C++ compiler always recognizes the keyword.

The syntax is as follows:
Read syntax diagramSkip visual syntax diagram
asm statement syntax — statement in local scope

>>-+-asm-----+--+----------+------------------------------------>
   +-__asm---+  '-volatile-'   
   '-__asm__-'                 

>--(--code_format_string--+------------------------------------------------------+--)-><
                          '-:--+--------+--+-----------------------------------+-'      
                               '-output-'  '-:--+-------+--+-----------------+-'        
                                                '-input-'  '-:--+----------+-'          
                                                                '-clobbers-'            

input

   .-,--------------------------------------------.   
   V                                              |   
|----+----------+--constraint--(--C_expression--)-+-------------|
     '-modifier-'                                     

output

   .-,----------------------------------------.   
   V                                          |   
|----modifier--constraint--(--C_expression--)-+-----------------|

Read syntax diagramSkip visual syntax diagram
asm statement syntax — statement in global scope

>>-+-asm-----+--(--code_format_string--)-----------------------><
   +-__asm---+                             
   '-__asm__-'                             

The qualifier volatile instructs the compiler that the assembler instructions may update memory not listed in output, input, or clobbers.

The code_format_string is the source text of the asm instructions and is a string literal similar to a printf format specifier. Depending on the operands taken by the assembly instruction, the string contains zero or more modifiers, each of which corresponds to an input or output operand, separated by commas.

The % modifier can take either of the following forms:
  • %integer, where integer refers to the sequential number of the input or output operand.
  • %[symbolic_name], where the symbolic_name is referenced in the operand list. The symbolic operand names have no relation to any C identifiers. Any name can be used, even those of existing C symbols. However, no two operands in the same assembly statement can use the same symbolic name.

The input consists of zero, one or more input operands, separated by commas. Each operand consists of a constraint(C_expression) pair.

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.

The modifier is one of the following:
=
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.
&
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.
The constraint is a string literal that describes the kind of operand that is permitted, one character per constraint. The following constraints are supported:
b
Use a general register other than zero.
c
Use the CTR register.
f
Use a floating-point register.
g
Use a general register, memory, or immediate operand.
h
Use the CTR or LINK register.
i
Use an immediate integer or string literal operand.
l
Use the CTR register.
m
Use a memory operand supported by the machine.
n
Use an immediate integer.
o
Use a memory operand that is offsetable.
r
Use a general register.
s
Use a string literal operand.
v
Use a vector register.
0, 1, 2, …
A matching constraint. Allocate the same register in output as in the corresponding input.
I, J, K, L, M, N, O, P
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
  • M — unsigned constant greater than 31
  • N — unsigned constant that is an exact power of 2
  • O — zero
  • P — signed whose negation is a signed 16-bit constant

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.

Note: If pointer expressions are used in input or output, the assembly instructions should honor the ANSI aliasing rule (see Type-based aliasing for more information). This means that indirect addressing using values in pointer expression operands should be consistent with the pointer types; otherwise, you must disable the -qalias=ansi option during compilation.
clobbers is a comma-separated list of register names enclosed in double quotes. These are registers that can be updated by the asm instruction. The following are valid register names:
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
v0 to v31
Vector registers (on selected processors only)