Lecture 5 - Subroutine
Lecture 5 - Subroutine
Subroutine
Example
...
EXPORT __main
IMPORT copy_array
...
__main
LDR r0, =array2 ;Load source address
LDR r1, =0x40000000 ;Load destination address
LDR r2, =len ;Load the length of data
BL copy_array ;Copy data from src to dest
...
Done
B Done
END
Example
Source: http://www.davespace.co.uk/arm/introduction-to-arm/img/dia/call.png
Branch / Branch with Link
Syntax:
B{L}{<cond>} <target address>
31 28 27 25 24 23 0
cond 101 L 24-bit signed word offset
Source: http://www.learnme.in/wp-content/uploads/2013/01/Stacks.png
Stack
Source: http://www.csit.parkland.edu/~mbrandyberry/CS2Java/Lessons/Stack_Queue/Stacks.shtml
Stack
• Stack is a form of last-in-first-out store
• It is usually implemented as a linear data structure which
grows up (an ascending stack) or down (a descending stack)
memory as data is added to it and shrinks back as data is
removed.
• Stack pointer holds the address of the current top of the
stack.
– It can point to either the last valid data item pushed on the stack (a full stack)
OR
– the vacant slot where the next data item will be placed (an empty stack)
• ARM multiple register transfers support all forms of stack
Stack operations
Full ascending stack (FA)
It grows up through increasing memory addresses and the base register points to the
highest address containing a valid item - stack pointer that points to the last used (full)
location.
Empty ascending stack (EA)
It grows up through increasing memory addresses and the base register
points to the first empty location above the stack - stack pointer that
points to the first unused (empty) location.
Full descending stack (FD)
It grows down towards decreasing memory addresses (towards the
bottom of memory) and the base register points to the lowest address
containing a valid item
Empty descending stack (ED)
It grows down towards decreasing memory addresses and the base
register points to first empty location below the stack
Stack Types
Syntax
LDM{<cond>}<addressing_mode> Rn{!}, <regs>{^}
STM{<cond>}<addressing_mode> Rn{!}, <regs>{^}
<addressing_mode>
– IA – Increment by 4 After transfer LDMIA
– IB – Increment by 4 Before transfer LDMIB
– DA – Decrement by 4 After transferLDMDA
– DB – Decrement by 4 Before transfer LDMDB
• Register write-back controlled by “!”
• Registers are always written/read from memory with lowest register number in
the lowest address
Load/Store Multiple
Syntax
LDM{<cond>}<addressing_mode> Rn{!}, <regs>{^}
STM{<cond>}<addressing_mode> Rn{!}, <regs>{^}
<regs> = {rn,..rm}
– The {rn,..rm} list may contain any or all of r0 - r15
– It doesn’t matter how the registers are ordered in {…}
– The lowest register always uses the lowest address, and so on, in
increasing order
Instruction format
31 28 27 25 24 23 22 21 20 19 16 15 0
base register
load/store
write-back (auto-index)
restore PSR and force user bit
up/down
pre-/post-index
Syntax
LDM|STM{<cond>}<addr> Rn{!},<regs>{^}
<addr> = IA etc
<regs> = {rn,..rm}
Example
LDMIA r1,{r5,r0,r2} ; r0 := mem[r1]
; r2 := mem[r1+4]
; r5 := mem[r1+8]
Source: http://www.davespace.co.uk/arm/introduction-to-arm/img/dia/call.png
Example undef
undef
LDR sp, =XXXX ;initialize the stack pointer
undef
...
test_pt1 BL sub1 ;call first subroutine undef
undef
undef undef
R14(1)
sub1 STMFD sp!, {r4, lr} ;save return address and r4 R4(1)
... undef
s1_pt1 BL sub2 undef
s1_pt2 LDMFD sp!, {r4, pc} ;return and restore r4 undef
undef
undef
R14(1)
R4(1)
sub2 STMFD sp!, {r4, r7, lr} ;save return address, r4 and r7
... R14(2)
s2_pt1 ... R7(2)
s2_pt2 LDMFD sp!, {r4, r7, pc} ;return and restore r4 and r7
R4(2)
undef
Example undef
R14(1)
R4(1)
LDR sp, =XXXX ;initialize the stack pointer
... R14(2)
test_pt1 BL sub1 ;call first subroutine R7(2)
test_pt2 ...
R4(2)
Undef
undef
sub1 STMFD sp!, {r4, lr} ;save return address and r4 R14(1)
... R4(1)
s1_pt1 BL sub2
R14(2)
s1_pt2 LDMFD sp!, {r4, pc} ;return and restore r4
R7(2)
R4(2)
undef
undef
R14(1)
R4(1)
sub2 STMFD sp!, {r4, r7, lr} ;save return address, r4 and r7
... R14(2)
s2_pt1 ... R7(2)
s2_pt2 LDMFD sp!, {r4, r7, pc} ;return and restore r4 and r7
R4(2)
undef
Passing Parameters to Subroutines
21
Example
SRAM_BASE EQU 0x40000000
...
LDR sp, =SRAM_BASE
MOV r0, #0x30 ;coeff.
MOV r1, #1 ;plain text
BL cipher
...
Cipher
STMIA sp!, {r6,lr} ;preserve reg
ADD r6, r0, r1 ;cipher algor.
MOV r1, r6 ;result
LDMDB sp!, {r6,pc} ;return
END
22
Passing Parameters to Subroutines
23
Example
SRAM_BASE EQU 0x40000000
...
LDR sp, =SRAM_BASE ;stack pointer
LDR r3, =SRAM_BASE+100 ;for params
END
24
Passing Parameters to Subroutines
25
Example
SRAM_BASE EQU 0x40000000
...
LDR sp, =SRAM_BASE ;stack pointer
END
26
APCS
ARM Procedure Call Standard (APCS)
• In some areas it is important to adopt software-
defined ‘standard’ solutions
– the ARM Procedure Call Standard (APCS) is an
example
• it provides a regular way for procedures to operate
• The APCS defines:
– particular uses for the ‘general-purpose’ registers
– the form of stack to be used
– a stack-based data structure for back-tracing when
debugging the program
– a function argument and result passing mechanism
Application Procedure Call Standard
• r0-r3 r0
Arguments into function
– Pass argument values to a subroutine Result(s) from function
r1
r2
– Return a result value from a subroutine Otherwise corruptible r3
– Hold intermediate values within a
r4
subroutine r5
• r4-r8, r10, and r11 r6
Register variables r7
– Routine’s local variable must be preserved r8