mspgcc's ABI

Register usage

If you intend to interface assembly routines with your C code, you need to know how GCC uses the registers. This section describes how registers are allocated and used by the compiler. (You can override GCC's settings by issuing -ffixed-regs=...)

r0, r2, and r3 - are fixed registers and not used by the compiler in any way. They cannot be used for temporary register arguments either.

r1 - is the stack pointer. The compiler modifies it only in the function prologues and epilogues, and when a function call with a long argument list occurs. Do not modify it yourself under any circumstances!!!

r4 - is the frame pointer. This can be used by the compiler, when va_args is used. When va_args is not used, and optimization is switched on, this register is eliminated by the stack pointer.

r5 - argument pointer. This can be used by the compiler, when a function call with a long argument list is performed. It refers to the stack position before the function call. Normally, when optimization is turned on, this register usage is eliminated and the argument list is accessed via the stack pointer.

Use the last two with care. If GCC uses them as these pointers, their values, after the function's prologue are:

where r1 is its value on function entry, minus the size of registers pushed in the prologue.

r12, r13, r14, and r15 - are call cloberred (in general) registers. If you are interfacing C with assembler language, you do not have to save these registers, except in interrupt service routines.

*** NOTE *** some library calls (such as divmodM, mulM) clobber some registers (r8 - r11). GCC allows for this during code generation, and will save clobbered registers on the stack in the calling function.

All other registers are caller used registers. If you are interfacing C with assembler language, you must save them on the stack and restore them before exit.

Registers are allocated in the order r12 to r15, r11 to r0. Please use this order if you plug in assembly language functions.

char, int and pointer variables take one register. long and float variables take two registers, in little-endian order (i.e. the LSB goes in lower numbered register). long long int variables take 4 registers, in little-endian order.