5.12.2 Inline Assembly
Assembly instructions can be directly embedded in-line into C code using
the statement asm();
.
The instructions are placed in a string inside what look like function
call brackets, although no actual call takes place. Typically one instruction is placed in
the string, but you can specify more than one assembly instruction by separating the
instructions with a \n
character, e.g., asm("movlw 55\nmovwf
_x");
, code will be more readable if you place one instruction in each
statement and use multiple statements.
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 interact with compiler-generated code. The code generator cannot scan the assembler code for register usage; so 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 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 5.6 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 the rest of the program changes, 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 (see 5.9.7 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-lined assembly if the containing function might be duplicated.