5.12.2 In-line Assembly
Assembly instructions can be directly embedded in-line into C code using
the statement __asm();
. The asm()
form of this statement
may also be used, although it is not recommended.
The required instructions are placed as string literals in brackets.
Although they look like function arguments, no actual call takes place. Typically, one
instruction is placed in each statement to enhance code readability, but you can specify
more than one assembly instruction in one statement by separating the instructions with a
\n
character, e.g., __asm("movlw 55\nmovwf _x");
.
You can use the __asm()
form of in-line assembly at any
point in the C source code as it will correctly interact with all C flow-of-control
structures, as shown below.
unsigned int var;
int main(void)
{
var = 1;
__asm("bcf 0,3");
__asm("BANKSEL _var");
__asm("rlf (_var)&07fh");
__asm("rlf (_var+1)&07fh");
}
In-line assembly code is never optimized by the assembler optimizer.
When using in-line assembler code, it is extremely important that you do not corrupt resources used by compiler-generated code. The code generator cannot scan the assembler code for register usage; thus, it remains unaware if registers are clobbered or used by the assembly code. However, the compiler will reset all bank tracking once it encounters in-line assembly, so any Special Function Registers (SFRs) or bits within SFRs that specify the current bank do not need to be preserved by in-line assembly.
The registers used by the compiler are explained in Register Usage. If you are in doubt as to which
registers are being used in surrounding code, compile your program with the
-Wa,-a
option and examine the assembler code generated by the compiler.
Remember that as your program is modified, the registers and code strategy used by the
compiler will change as well.
If a C function is called from main-line and interrupt code, it can be duplicated by the compiler (see Function Duplication). Although a special prefix is used to ensure that labels generated by the compiler are not duplicated, this does not apply to labels defined in hand-written, in-line assembly code in C functions. Thus, you should not define assembly labels for in-line assembly if the containing function might be duplicated.