Register usage in subroutine calls
You use branch instructions to call and return from subroutines. The Procedure Call Standard for the Arm® Architecture defines how to use registers in subroutine calls.
A subroutine is a block of code that performs a task based on some arguments and optionally returns a result. By convention, you use registers R0 to R3 to pass arguments to subroutines, and R0 to pass a result back to the callers. A subroutine that requires more than four inputs uses the stack for the additional inputs.
To call subroutines, use a branch and link instruction. The syntax is:
BL destination
where
is usually
the label on the first instruction of the subroutine.destination
can also be a
PC-relative expression.destination
The BL
instruction:
- Places the return address in the link register.
- Sets the PC to the address of the subroutine.
After the subroutine code has executed you can use a BX LR
instruction to
return.
Note
Calls between separately assembled or compiled modules must comply with the restrictions and conventions defined by the Procedure Call Standard for the Arm® Architecture.Example
The following example shows a subroutine, doadd
, that adds the values of
two arguments and returns a result in R0
:
AREA subrout, CODE, READONLY ; Name this block of code ENTRY ; Mark first instruction to execute start MOV r0, #10 ; Set up parameters MOV r1, #3 BL doadd ; Call subroutine stop MOV r0, #0x18 ; angel_SWIreason_ReportException LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit SVC #0x123456 ; AArch32 semihosting (formerly SWI) doadd ADD r0, r0, r1 ; Subroutine code BX lr ; Return from subroutine END ; Mark end of file