ARM Calling Standard
A calling standard or convention is a prefined way of using the registers and making
subroutine calls. Following the convention allows your code to work with code produced
by others and by the tools.
Each processor family has its own calling standard.
Argument registers
- R0 - R3
- Used to pass arguments to subroutines
- Subroutines can use them as scratch registers
- If they have important data before the call, the calling routine must save the data before the call.
- Caller saved
Register Variables
- R4 - R8, and R9 - R10
- Callee saved
- Subroutine must preserve their data
- Return intact after the call
Link Register
- R15 (LR)
- Return address - Link back to caller
- Typical to save it to the stack and restore it to the PC
Stack Pointer
- R13 (SP)
- Typically pointer to full descending stack
- Typically auto indexed
- STMFD sp!, {regs, lr}
- LDMFD sp!, {regs, pc}
Static Base
- R9
- Offset for position independent code
- Used for re-entrant code ROM code, and shared libraries
Frame Pointer
- R11
- The frame pointer register, which is used to access automatic variables in the stack frame.
Argument Passing
- Everything is organized as a list of words
- The first four words are passed in R0-R3
- The rest are pushed onto the stack in reverse order.
Return Result
- Return is in R0 or R0-R4 depending on the size of the return value. Or pointer to memory in R0.
- Simple results such as ints, are passed back in R0.
- More complex values are written to memory at the address passed in through R0 as the first argument. The caller allocates the memory before the call.
Possible optimizations
- When functions require a lot of parameters pass a pointer to a struct with the parameters instead of passing the paramters directly.
- Include the caller and the callee in the same C file so the compiler can improve the call depending on the the callee’s register use.
- Use inline functions