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.