Professional Documents
Culture Documents
Example: uprcase
Repetition
Repetition
Example: uprcase
Subroutines
Subroutine implementation
Call/return example
uprcase (address)
{
while ((char = Memory.byte[address])
!= NULL) {
if (char a AND char z) {
char = char AND 0xFFFFFFDF
Memory.byte[address] = char
}
address = address + 1
}
}
...
R14, pc
sub1
???, ???, ???
...
;
; save return address
; branch to the subroutine (labelled sub1)
; some random instruction after the branch
;
...
???, ???, ???
pc, R14
;
; last subroutine instruction
; return to the calling program
8
...
R14, pc
sub1
???, ???, ???
...
;
; save return address
; branch to the subroutine (labelled sub1)
; some random instruction after the branch
;
...
sub1
???, ???, ???
...
;
; branch to the sub1, saving return address
; some random instruction after the branch
;
Subroutines
...
???, ???, ???
pc, lr
;
; last subroutine instruction
; return to the calling program
...
???, ???, ???
lr
;
; last subroutine instruction
; return to the calling program
start
stop
LDR
BL
r1, =str1
uprcase
LDR
BL
r1, =str2
uprcase
stop
;
; Define strings to test program
;
str1
str2
AREA
DCB
DCB
11
Subroutine
label for 1st instruction
in subroutine
uprcase
wh1
endif1
testwh1
testwh1
CMP
BCC
CMP
BHI
BIC
STRB
r0, #'a'
endif1
r0, #'z'
endif1
r0, #0x00000020
r0, [r1, #-1]
LDRB
CMP
BNE
BX
r0, [r1], #1
r0, #0
wh1
lr
12
Nested subroutines
Subroutines
; call sub1
stop
; sub1 subroutine
sub1
BL
sub2
BX
lr
; call sub2
; return from sub1
; sub2 subroutine
sub2
BX
lr
13
Subroutines
Solution
Save the contents of the link register before a subroutine
invokes a further nested subroutine
Restore the contents of the link register when the nested
subroutine returns
Where should we save the contents of the link register?
sp!, {lr}
sub2
sp!, {lr}
lr
;
;
;
;
Subroutines
sp!, {lr}
...
...
sp!, {lr}
lr
...
sp!, {pc}
16
Subroutines
LDR
LDR
r0, =deststr
r1, =teststr
BL
uprcase
; uprcase(ptr2)
LDRB
STRB
CMP
BNE
r2, [r1], #1
r2, [r0], #1
r2, #0
do1
; do {
; ch = Memory.Byte[ptr1++]
; Memory.Byte[ptr2++] = ch
; } while (ch != NULL);
;
stop
...
...
DCB
SPACE
"xerox",0
256
do1
stop
teststr
deststr
END
17
endif1
testwh2
CMP
BCC
CMP
BHI
BIC
STRB
r0, #'a'
endif1
r0, #'z'
endif1
r0, #0x00000020
r0, [r1, #-1]
LDRB
CMP
BNE
LDMFD
r0, [r1], #1
r0, #0
wh2
sp!, {pc}
endif1
testwh2
CMP
BCC
CMP
BHI
BIC
STRB
r0, #'a'
endif1
r0, #'z'
endif1
r0, #0x00000020
r0, [r1, #-1]
LDRB
CMP
BNE
LDMFD
r0, [r1], #1
r0, #0
wh2
sp!, {r0-r1,pc}
Any registers used are saved on the stack (along with the link
register) at the start of the subroutine
These are restored before returning
20
Passing parameters
21
Example: fillmem
3 parameters
address start address in memory
length number of words to store
value value to store
22
First version
; fillmem subroutine
; Fills a contiguous sequence of words in memory with the same value
; parameters
r0: address address of first word to be filled
;
r1: length number of words to be filled
;
r2: value value to store in each word
fillmem
STMFD
sp!, {r0-r2,r4,lr} ; save registers
MOV
r4, #0
; count = 0;
wh1
CMP
r4, r1
; while (count < length)
BHS
endwh1
; {
STR
r2, [r0, r4, LSL #2] ; Memory.Word[address] = value;
ADD
r4, #1
; count = count + 1;
B
wh1
; }
endwh1
;
LDMFD
sp!, {r0-r2,r4,pc} ; restore registers
Second version
; fillmem subroutine
; Fills a contiguous sequence of words in memory with the same value
; parameters
r0: address address of first word to be filled
;
r1: length number of words to be filled
;
r2: value value to store in each word
fillmem
STMFD
sp!, {r0-r1,lr}
; save registers
CMP
r1, #0
; while (length != 0)
B
testwh1
; {
wh1
STR
r2, [r0], #4
; Memory.Word[address] = value;
; address = address + 4;
SUBS
r1, #1
; length = length 1;
testwh1 BNE
wh1
; }
LDMFD
sp!, {r0-r1,pc}
; restore registers
24
Parameters
Example: count1s
Subroutines
word
count of set bits
word in which 1s will be counted
; save registers
; count = 0;
;
;
;
;
;
;
;
while (wordval != 0)
{
wordval = wordval >> 1; (update carry)
count = count + 0 + carry;
}
restore registers
26
Example: count1s
count Parameter
variable parameter
used to return the count of 1s to the calling program
changes made by the subroutine should be visible to the
calling program
should not be saved (and restored) on the stack
wordval parameter
value parameter
used to pass the word in which 1s are to be counted to the
count1s subroutine
should be saved / restored on the stack at the start / end of
the subroutine to hide any modifications
27
Parameters
Example
Design and write an ARM Assembly Language subroutine that
will add two 128-bit integers
Require 4 words for each operand and 4 words for the result
29
Example: add128
Subroutines
r1, =val1
r2, =val2
r0, =result
BL
add128
stop
stop
;
;
;
...
...
<the subroutine will go here>
...
...
val1
val2
result
AREA
DCD
DCD
SPACE
0x57FD30C2,0x387156F3,0xFE4D6750,0x037CB1A0
0x02BA862D,0x298B3AD4,0x213CF1D2,0xFD00357C
16
Example: add128
Subroutines
; add128 subroutine
; Adds two 128-bit integers
; Parameters
r0: pResult (val) - result
;
r1: pVal1 (val) - first integer
;
r2: pVal2 (val) - second integer
add128
STMFD
sp!, {r0-r2,r5-r7,lr} ; save registers
LDR
LDR
ADDS
STR
r5,
r6,
r7,
r7,
[r1], #4
[r2], #4
r5, r6
[r0], #4
;
;
;
;
LDR
LDR
ADCS
STR
r5,
r6,
r7,
r7,
[r1], #4
[r2], #4
r5, r6
[r0], #4
;
;
;
;
LDR
LDR
ADCS
STR
r5,
r6,
r7,
r7,
[r1], #4
[r2], #4
r5, r6
[r0], #4
;
;
;
;
LDR
LDR
ADCS
STR
r5,
r6,
r7,
r7,
[r1], #4
[r2], #4
r5, r6
[r0], #4
;
;
;
;
LDMFD
Example
General approach
Calling program pushes parameters onto the stack
Subroutine accesses parameters on the stack, relative to the
stack pointer
Calling program pops parameters off the stack after the
subroutine has returned
33
Example: fillmem
34
stop
tstarea
LDR
LDR
LDR
r0, =tstarea
r1, =32
r2, =0xC0C0C0C0
STR
STR
STR
BL
fillmem
ADD
stop
AREA
SPACE
256
END
35
Subroutines
wh1
LDR
LDR
LDR
MOV
CMP
BHS
STR
ADD
B
r4, #0
; count = 0;
r4, r1
; while (count < length)
endwh1
; {
r2, [r0, r4, LSL #2] ; Memory.Word[address] = value;
r4, #1
; count = count + 1;
wh1
; }
LDMFD
endwh1
36
Example: fillmem
Example: fillmem
Subroutines
Stack state
32 bits
0xA1001024
sp
0xA1001020
0xA100101C
0xA1001018
0xA1001014
0xA1001010
0xA100100C
0xA1001008
0xA1001004
0xA1001000
0xA1000FFC
0xA1000FF8
??
??
??
??
??
??
??
??
??
??
??
??
before
pushing
parameters
32 bits
0xA1001024
0xA1001020
0xA100101C
0xA1001018
sp
0xA1001014
0xA1001010
0xA100100C
0xA1001008
0xA1001004
0xA1001000
0xA1000FFC
0xA1000FF8
??
??
address
length
value
??
??
??
??
??
??
??
before
calling
subroutine
32 bits
0xA1001024
0xA1001020
0xA100101C
0xA1001018
0xA1001014
0xA1001010
0xA100100C
0xA1001008
0xA1001004
sp
0xA1001000
0xA1000FFC
0xA1000FF8
??
??
address
length
value
saved lr
saved r4
saved r2
saved r1
saved r0
??
??
subroutine
after saving
registers
38
wh1
STMFD
sp!, {r0-r4,lr}
; save registers
LDR
LDR
LDR
MOV
CMP
BHS
STR
ADD
B
r4, #0
; count = 0;
r4, r1
; while (count < length)
endwh1
; {
r2, [r0, r4, LSL #2] ; Memory.Word[address] = value;
r4, #1
; count = count + 1;
wh1
; }
LDMFD
sp!, {r0-r4,pc}
endwh1
; restore registers
Subroutines
fillmem
STMFD
ADD
STMFD
; save r12, lr
; scratch = sp + 8
; save registers
LDR
LDR
LDR
sp!, {r0-r4}
sp!, {r12, pc}
; restore registers
; restore r12, pc
40
Subroutines
Stack state
32 bits
0xA1001024
sp
0xA1001020
0xA100101C
0xA1001018
0xA1001014
0xA1001010
0xA100100C
0xA1001008
0xA1001004
0xA1001000
0xA1000FFC
0xA1000FF8
??
??
??
??
??
??
??
??
??
??
??
??
before
pushing
parameters
32 bits
0xA1001024
0xA1001020
0xA100101C
0xA1001018
sp
0xA1001014
0xA1001010
0xA100100C
0xA1001008
0xA1001004
0xA1001000
0xA1000FFC
0xA1000FF8
??
??
address
length
value
??
??
??
??
??
??
??
before
calling
subroutine
32 bits
0xA1001024
0xA1001020
0xA100101C
0xA1001018
r12
0xA1001014
0xA1001010
0xA100100C
0xA1001008
0xA1001004
sp
0xA1001000
0xA1000FFC
0xA1000FF8
??
??
address
length
value
saved r12
saved lr
saved r4
saved r2
saved r1
saved r0
??
subroutine
after saving
registers
41
ARM APCS
ARM APCS
Subroutines
Notes
r0
r1
r2
r3
r4
r5
r6
r7
Variables
r8
Must be preserved
r9
r10
r11
r12
r13
r14
r15
43
Recursion
Subroutines
1
x
n
x 2 n/2
x n/2
x. x 2
if n 0
if n 1
if n is even
if n is odd
44
Example: power
Pseudo-code solution
power (x, n)
{
if (n == 0)
{
result = 1;
}
else if (n == 1)
{
result = x;
}
else if (n & 1 == 0)
{
result = power (x . x, n >> 1);
}
else
{
result = x . power (x . x, (n 1) >> 1)
}
}
45
Example: power
; power subroutine
; Compute x^n
; Parameters:
;
;
power
STMFD
else11
else12
CMP
BNE
MOV
B
CMP
BNE
MOV
B
TST
BNE
MOV
MUL
MOV
BL
B
Subroutines
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
if (n == 0)
{
result = 1;
}
else if (n == 1)
{
result = x;
}
else if (n & 1 == 0)
{
tmpx = x;
x = tmpx * x;
n = n / 2;
result = power (x, n);
}
Example: power
Subroutines
; else {
; tmpx = x;
; x = x * tmpx;
; n = n - 1;
; n = n / 2;
; result = power (x, n);
; result = tmpx * result;
; }
MOV
MUL
SUB
MOV
BL
MUL
r4, r1
r1, r4,
r2, r2,
r2, r2,
power
r0, r4,
LDMFD
endif1
r1
#1
LSR #1
r0
47