Control Flow and Subroutines ​
Complete Lab Manual
For the complete experiment including learning objectives, theoretical background, and detailed explanations, download the PDF manual: Download Experiment 3 PDF
Examples ​
Example 1: Find Maximum Element in Array ​
This example demonstrates how to find the maximum element in an array using a standard for loop structure.
AREA RESET, CODE, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000 ; Initial SP
DCD Reset_Handler ; Reset vector
ALIGN
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
; Find maximum element in ARR[0..LEN-1]
; Result (max) is written to MAXRES.
Reset_Handler
LDR R0, =ARR ; R0 = &ARR[0]
MOV R1, #0 ; R1 = i (index)
LDR R2, [R0] ; R2 = max = ARR[0]
for_start
CMP R1, #LEN ; i >= LEN ?
BGE for_end ; yes -> done
LDR R3, [R0, R1, LSL #2]; R3 = ARR[i]
CMP R3, R2 ; if ARR[i] > max
MOVGT R2, R3 ; max = ARR[i]
ADD R1, R1, #1 ; i++
B for_start
for_end
LDR R4, =MAXRES ; store result for easy checking
STR R2, [R4]
STOP B STOP
AREA CONSTANTS, DATA, READONLY
ARR DCD 10, 20, 30, -5, 11, 0
LEN EQU 6
AREA MYDATA, DATA, READWRITE
MAXRES DCD 0 ; expect 30
ENDCheck: Verify that the maximum element is correctly identified and stored in MAXRES.
Example 2: Count Uppercase Letters in String ​
This example demonstrates how to process a null-terminated string and count the number of uppercase letters (A-Z) using a while-loop structure.
AREA RESET, CODE, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000 ; Initial SP
DCD Reset_Handler ; Reset vector
ALIGN
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
; Count uppercase ASCII letters in the null-terminated string MYSTR.
; Result (count) is written to UPPERCOUNT.
Reset_Handler
LDR R0, =MYSTR ; R0 = ptr to string
MOV R1, #0 ; R1 = count
while_next
LDRB R2, [R0], #1 ; R2 = *p++; post-increment pointer
CBZ R2, while_end ; if '\0' -> exit
CMP R2, #'A' ; below 'A'?
BLT while_next
CMP R2, #'Z' ; above 'Z'?
BGT while_next
ADD R1, R1, #1 ; count++
B while_next
while_end
LDR R3, =UPPERCOUNT
STR R1, [R3]
STOP B STOP
AREA CONSTANTS, DATA, READONLY
MYSTR DCB "Hello ARM World!", 0
AREA MYDATA, DATA, READWRITE
UPPERCOUNT DCD 0 ; expect 5 ('H','A','R','M','W')
ENDCheck: Verify that the program correctly counts the uppercase letters and stores the result in UPPERCOUNT.
Example 3: Nested Uppercase Counter with Stack ​
This example demonstrates a nested call: CountUpperNested(ptr) scans a null-terminated string and calls IsUpper(ch) for each character. It shows saving/restoring LR and using a callee-saved register (R4) for the running count.
AREA RESET, CODE, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000 ; Initial SP
DCD Reset_Handler ; Reset vector
ALIGN
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
IsUpper ; IsUpper(R0 = ch) -> R0 = 1 if 'A'..'Z', else 0
CMP R0, #'A'
BLT not_upper
CMP R0, #'Z'
BGT not_upper
MOV R0, #1
BX LR
not_upper
MOV R0, #0
BX LR
CountUpperNested ; CountUpperNested(R0 = ptr) -> R0 = Upper Count
PUSH {R4, LR} ; save callee-saved + return address
MOV R1, R0 ; R1 = ptr (keep pointer here)
MOV R4, #0 ; R4 = count
cu_next
LDRB R0, [R1], #1 ; R0 = *ptr++; post-increment pointer in R1
CBZ R0, cu_done ; if null terminator, finish
BL IsUpper ; R0 = 0/1 based on 'A'..'Z'
ADD R4, R4, R0 ; count += result
B cu_next
cu_done
MOV R0, R4 ; return count in R0
POP {R4, PC}
Reset_Handler
LDR R0, =mystring
BL CountUpperNested
LDR R2, =UPPERCOUNT
STR R0, [R2]
STOP B STOP
AREA CONSTANTS, DATA, READONLY
mystring DCB "Hello ARM World!", 0 ; Uppercase: H, A, R, M, W -> 5
AREA MYDATA, DATA, READWRITE
UPPERCOUNT DCD 0 ; should be 5
ENDCheck: Verify that UPPERCOUNT contains 5 for the test string.
Tasks ​
Task 1: Count Vowels in a String ​
Implement procedures to process strings with the following requirements:
- Create a procedure
CountVowelsthat takes a string pointer in R0 and returns the number of vowels (a, e, i, o, u) in R0. - Use nested procedure calls where
CountVowelscalls a helper procedureIsVowel. - Follow AAPCS conventions for parameter passing and register usage.
Task 2: Factorial Calculation (Iterative) ​
Implement a procedure to calculate the factorial of a non-negative integer:
- Create a procedure
Factorialthat takes a non-negative integer in R0 and returns its factorial in R0. - Use an iterative approach with a loop to compute the factorial.
- Ensure proper handling of edge cases, such as 0! = 1.
- Follow AAPCS conventions for parameter passing and register usage.
Task 3: Factorial Calculation (Recursive) ​
Implement a recursive version of the factorial calculation:
- Create a procedure
FactorialRecthat takes a non-negative integer in R0 and returns its factorial in R0. - Use recursion to compute the factorial, ensuring proper base case handling.
- Manage the stack appropriately to save and restore registers as needed.
- Follow AAPCS conventions for parameter passing and register usage.
- Test the procedure with various inputs to verify correctness.