06 Subroutines in ARM
06 Subroutines in ARM
The block of instructions that constitute a subroutine can be included at every point in the main
program when that task is needed. However, this would result in unnecessary waste of memory
space. Rather, only one copy of the instructions that constitute the subroutine is placed in
memory and can be accessed repeatedly.
Components of Subroutines
Calling Subroutines
2. Once the subroutine is complete, it should return back to the place that called the sub-
routine.
There are special instructions for transferring control to subroutines and restoring control to
the main program. The instruction that transfers the control is usually termed as call, jump or
branch to subroutine. The calling program is called Caller and the subroutine called is known
as Callee. The instruction that transfer control back to the caller is known as Return.
61
62 CHAPTER 6. SUBROUTINES IN ASSEMBLY LANGUAGE
Calling a subroutine requires a deviation from the default sequential execution of instructions.
When a program branches to a subroutine, the processor begins execution of the instructions
that make up the subroutine and branch to the subroutine by modifying the Program Counter
(PC). In ARM, the Branch and Link instruction (BL) is used to Branch to subroutine.
Example 6.1
This instruction saves the current address of program counter (PC) in the link register (LR)
before placing the starting address of the subroutine in the program counter.
When the subroutine has completed its task, the processor must be able to branch back (return)
to the instruction immediately following the branch instruction that invoked the subroutine. To
return from the subroutine we move the value stored in the link register to program counter
which returns the control to the next instruction from which subroutine was called. Thus, to
return from subroutine we should use the following instruction:
Example 6.2
The ARM Application Procedure Call Standard (AAPCS) for the ARM architecture defines
how subroutines can be independently written, separately complied, and assembled to work
together. Some parts of the specifications are listed below:
• The first four registers R0 R3 are used to pass argument values into a subroutine and to
return a result value from a function.
• The registers R4 R8, R10, and R11 are normally used to hold the values of a routine’s
local variables.
• ARM and THUMB, C and C++ compilers always use a full descending stack and it must
be eight-byte aligned.
Although your program may work without conforming to the above specification, it is a good
practice to have these specifications in mind. In particularly, when calling between C, C++,
63
and assembly language is needed, assembly language modules must conform to the appropriate
AAPCS standard.
Parameter Passing
When calling a subroutine, a calling program needs a mechanism to provide to the subroutine
the input parameters, the operands that will be used in computation in the subroutine or their
addresses. Later, the subroutine needs a mechanism to return output parameters, the results
of the subroutine computation. This exchange of information between a calling program and
a subroutine is referred to as parameter passing. Parameter passing may be accomplished in
three different ways:
The registers often provide a fast, convenient way of passing parameters and returning results.
Number of available registers limit the usefulness of this method. This method can result in
unforeseen side effects and it also lacks generality.
This is the simplest method to pass the parameters via the registers. Memory addresses,
counters and other data can be passed to the subroutines through registers. For example,
a subroutine takes two strings of equal length as its input parameters. The length of the strings
can be passed through the register R0 and the starting address of both the strings can be passed
via the registers R1 and R2 respectively.
Example 6.3
MOV R0 , # S t r L e n g t h ; R0 c o n t a i n s t h e l e n g h t o f s t r i n g s
LDR R1 , = S t r i n g 1 ; R1 h a s t h e s t a r t i n g a d d r e s s o f f i r s t s t r i n g
LDR R2 , = S t r i n g 2 ; R2 h a s t h e s t a r t i n g a d d r e s s o f s e c o n d s t r i n g
BL my_subroutine ; Jump t o s u b r o u t i n e
Passing the parameter through the registers is easy and the subroutine assume that parameters
are already placed in the registers. Results of a subroutine can also returned in the registers or
the memory location to store the results can be passed as parameters via the registers. This
method is limited by the number of available registers.
64 CHAPTER 6. SUBROUTINES IN ASSEMBLY LANGUAGE
Types of Parameters
We can specify the parameters in various different ways that are described below:
pass-by-value
In this method actual values are placed in a parameter list. Pass by value means you are making
a copy in memory of the actual parameter’s value that is passed in, a copy of the contents of
the actual parameter. Changing the value in the subroutine will not change the actual value of
the parameter.
pass-by-reference
In this method the address of parameters are placed in the parameter list. Changing the value
of parameter in the subroutine will also change the actual value. You must be more careful
while using this method as some parameters may change their value even if you don’t intend to
do so.
pass-by-name
Instead of passing either the value or the reference of the parameter a string containing the
name of the parameter is passed. This method is flexible but time consuming as a lookup table
must be consulted every time to access the value of the variable.
ARM supports different branch instructions for conditional executions. Depending on the con-
dition these instructions transfer the control from one part of the program to other. Unlike
Branch-and-Link (BL) instruction they do not save contents of Program counter (PC) register
to the Link Register (LR).
65
Examples
Now, we consider some examples of subroutines. Parameters are passed through the registers
and results are stored in memory through the registers.
Example 6.4
PRESERVE8
THUMB
__main
LDR R1 , N ; L o a d c o u n t i n t o R1
MOV R0 , #0 ; C l e a r a c c u m u l a t o r R0
BL SUMUP ; C a l l t h e s u b r o u t i n e SUMUP
Example 6.5
PRESERVE8
THUMB
__main
LDR R0 , = V a l u e 1 ; L o a d s t a r t i n g a d d r e s s o f f i r s t 64− b i t no .
LDR R1 , = V a l u e 2 ; L o a d s t a r t i n g a d d r e s s o f s e c o n d 64− b i t no .
BL SUM64
LDR R0 , = R e s u l t
STR R6 , [ R0 ] ; S t o r e h i g h e r 32− b i t s t o R e s u l t
STR R7 , [ R0 , # 4 ] ; S t o r e l o w e r 32− b i t s t o R e s u l t
B STOP
SUM64 PROC
LDR R2 , [ R0 ] ; L o a d t h e v a l u e o f h i g h e r 32− b i t s
LDR R3 , [ R0 , # 4 ] ; L o a d t h e v a l u e o f l o w e r 32− b i t s
LDR R4 , [ R1 ]
LDR R5 , [ R1 , # 4 ]
ADDS R7 , R3 , R5 ; Add w i t h f l a g s u p d a t e
ADC R6 , R2 , R4 ; Add w i t h c a r r y
BX LR
ENDP
STOP
67
END