Flow Control and Addressing Modes ​
In this experiment, you will learn how to implement looping, branching, and decision-making in ARM Assembly. Additionally, you will explore various addressing modes that ARM offers for flexible and efficient memory access.
Branching ​
Branching changes the program's execution flow by jumping to another location in memory.
- Unconditional branch:
B label
- Conditional branch: Executes only if a specific condition flag is set.
- Branch with Link (BL): Calls a subroutine.
- Branch and Exchange (BX): Returns from subroutine.
Conditional Execution ​
ARM supports conditional execution for most instructions by adding a condition suffix.
Condition Codes ​
Suffix | Meaning | Flags checked |
---|---|---|
EQ | Equal | Z = 1 |
NE | Not Equal | Z = 0 |
CS/HS | Carry Set / Unsigned ≥ | C = 1 |
CC/LO | Carry Clear / Unsigned < | C = 0 |
MI | Minus / Negative | N = 1 |
PL | Plus / Positive/Zero | N = 0 |
VS | Overflow Set | V = 1 |
VC | Overflow Clear | V = 0 |
HI | Unsigned > | C = 1 & Z = 0 |
LS | Unsigned ≤ | C = 0 or Z = 1 |
GE | Signed ≥ | N = V |
LT | Signed < | N ≠V |
GT | Signed > | Z = 0 & N = V |
LE | Signed ≤ | Z = 1 or N ≠V |
AL | Always (default) | — |
Load/Store Instructions ​
Load and Store Instructions have the following format:
asm
[LABEL] LDR{cond}{mod} Rt, [Rn{, #offset}]
[LABEL] STR{cond}{mod} Rt, [Rn{, #offset}]
Where:
<mod>
can be one of the following:B
- Byte (8 bits)H
- Halfword (16 bits)SB
- Signed Byte (8 bits)SH
- Signed Halfword (16 bits)D
- Doubleword (64 bits)
offset
can be a register, immediate value, or a barrel shifted value.cond
is an optional condition code.
Addressing Modes ​
Common ways to access memory in ARM:
Mode | Example | Description |
---|---|---|
Immediate | MOV R0, #15 | Constant operand |
Register | MOV R0, R1 | Operand in register |
Direct | LDR R0, VALUE | Value from memory label |
Indirect | LDR R0, [R1] | Value from address in register |
Pre-Indexed Without Update | LDR R0, [R1, #4] | Add offset before load (no update) |
Pre-indexed | LDR R0, [R1, #4]! | Add offset before load (update pointer) |
Post-indexed | LDR R0, [R1], #4 | Add offset after load |
Register Indexed | LDR R0, [R1, R2] | Base + register index |
Examples ​
Example 1: Looping Through an Array and a String ​
This program:
- Loops through an integer array using a length counter (pre-known size).
- Loops through a string until a null terminator is reached.
asm
AREA RESET, CODE, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000
DCD Reset_Handler
ALIGN
AREA M_DATA, DATA, READONLY
N DCD 5
ARRAY DCD 3, -7, 2, -2, 10
PTR_A DCD ARRAY
string1 DCB "Hello, ARM!", 0
PTR_S DCD string1
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
Reset_Handler
; ---- Array loop using length counter ----
LDR R1, N ; Number of elements
LDR R2, PTR_A ; Pointer to array
MOV R0, #0 ; Sum accumulator
arrayLoop
LDR R3, [R2], #4 ; Load next element, post-increment pointer
ADD R0, R0, R3
SUBS R1, R1, #1
BGT arrayLoop
; ---- String loop using null terminator ----
LDR R4, PTR_S ; Pointer to string
MOV R5, #0 ; Character counter
stringLoop
LDRB R6, [R4], #1 ; Load next char
CBZ R6, stringDone
ADD R5, R5, #1
B stringLoop
stringDone
STOP B STOP
END
Example 2 - Case Conversion of a Null-Terminated String ​
This program converts a null-terminated string to uppercase.
asm
AREA RESET, CODE, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000
DCD Reset_Handler
ALIGN
string DCB "Arm Assembly!", 0
AREA M_DATA, DATA, READWRITE
conv_str SPACE 13 ; Buffer for converted string (same length as input)
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
Reset_Handler
LDR R0, =string ; Pointer to input string
LDR R1, =conv_str ; Pointer to output buffer
caseConvLoop
LDRB R2, [R0], #1 ; Load byte from input and post-increment R0
CBZ R2, done ; If zero (end of string), jump to done
CMP R2, #'a' ; Compare char to 'a'
BLT storeChar ; If less, skip conversion, just store
CMP R2, #'z' ; Compare char to 'z'
BGT storeChar ; If greater, skip conversion, just store
BIC R2, R2, #32 ; Convert to uppercase by clearing bit 5
storeChar
STRB R2, [R1], #1 ; Store char to output buffer and post-increment
B caseConvLoop ; Loop back
done
MOV R2, #0
STRB R2, [R1] ; Null-terminate the output string
STOP
B STOP ; Infinite loop
END
Tasks ​
Task 1 - Sum All Even Numbers in an Array ​
- Write an ARM assembly program to sum all even integers from an array.
Task 2 - Count the Number of Vowels in a String ​
- Write an ARM assembly program to count the number of vowels (a, e, i, o, u) in a null-terminated string.