User guide

The LDR Rn, =expression pseudo-instruction is not supported. Use MOV Rn, expression instead (this
can generate a load from a literal pool).
Label expressions are not supported.
The ADR and ADRL pseudo-instructions are not supported.
The & operator cannot be used to denote hexadecimal constants. Use the 0x prefix instead. For example:
__asm {AND x, y, 0xF00}
The notation to specify the actual rotate of an 8-bit constant is not available in inline assembly language. This
means that where an 8-bit shifted constant is used, the C flag should be regarded as corrupted if the NZCV
flags are updated.
Physical registers, such as r0-r3, ip, lr, and the NZCV flags in the CPSR must be used with caution. If you use C
or C++ expressions, these might be used as temporary registers and NZCV flags might be corrupted by the
compiler when evaluating the expression.
Do not use C variables with the same name as a physical register. When accessed in an __asm block, the
actual register will be used instead of the variable. (It is possible to access the C variable by enclosing the name
in parentheses, but this behavior should not be relied upon.)
LDM and STM instructions only allow physical registers to be specified in the register list.
You cannot write to pc. The BX and BLX instructions are not implemented.
You should not modify the stack. This is not necessary because the compiler will stack and restore any working
registers as required automatically. It is not allowed to explicitly stack and restore work registers.
You can change processor modes, alter the ATPCS registers fp, sl, and sb, or alter the state of coprocessors,
but the compiler is unaware of the change. If you change processor mode, you must not use C or C++
expressions until you change back to the original mode because the compiler will corrupt the registers for the
processor mode to which you have changed.
Similarly, if you change the state of a floating-point coprocessor by executing floating-point instructions, you
must not use floating-point expressions until the original state has been restored.
4.1.4 Usage
The following points apply to using inline assembly language:
Comma is used as a separator in assembly language, so C expressions with the comma operator must be
enclosed in parentheses to distinguish them:
__asm {ADD x, y, (f(), z)}
If you are using physical registers, you must ensure that the compiler does not corrupt them when evaluating
expressions. For example:
__asm
{
MOV r0, x
ADD y, r0, x / y // (x / y) overwrites r0 with the result.
}
Because the compiler uses a function call to evaluate x / y, it:
corrupts r2, r3, ip, and lr
updates the NZCV flags in the CPSR
alters r0 and r1 with the dividend and modulo.
The value in r0 is lost. You can work around this by using a C variable instead of r0:
mov var,x
add y, var, x / y
The compiler can detect the corruption in many cases, for example when it requires a temporary register and
the register is already in use:
__asm
Mixing C, C++, and Assembly Language
Copyright ?1999 2001 ARM Limited 4-4