3. ARM Instruction Set
Data Processing Instructions
Data processing instructions are used to perform arithmetic, logical, and comparison operations on data stored in registers. These instructions can directly affect the Program Status Register (CPSR), particularly the condition flags (Zero, Negative, Overflow, Carry), which influence the execution of conditional instructions.
Instruction | Description | Example |
---|---|---|
MOV | Move an immediate value or the value from one register to another. | MOV R0, #5 (R0 = 5) |
ADD | Add two operands (registers or immediate values) and store the result in a destination register. | ADD R0, R1, R2 (R0 = R1 + R2) |
SUB | Subtract one operand from another and store the result. | SUB R0, R1, R2 (R0 = R1 - R2) |
MUL | Multiply two registers and store the result in a destination register. | MUL R0, R1, R2 (R0 = R1 * R2) |
AND | Perform a bitwise AND operation on two operands. | AND R0, R1, R2 (R0 = R1 & R2) |
ORR | Perform a bitwise OR operation on two operands. | ORR R0, R1, R2 (R0 = R1 |
EOR | Perform a bitwise Exclusive OR (XOR) operation on two operands. | EOR R0, R1, R2 (R0 = R1 ^ R2) |
Load/Store Instructions
Load/Store instructions are used to interact with memory. These operations typically involve transferring data between registers and memory addresses, making them essential for accessing variables, arrays, or structures.
| Instruction | Description | Example | | ———– | ————————————— | ——————————————————————————————– | | LDR | Load data from memory into a register. | LDR R0, [R1]
(Load value at address in R1 into R0) | | STR | Store data from a register into memory. | STR R0, [R1]
(Store value of R0 at address in R1) | | LDM | Load multiple registers from memory. | LDM R0, {R1, R2, R3}
(Load values from memory into R1, R2, R3 starting from address in R0) | | STM | Store multiple registers to memory. | STM R0, {R1, R2, R3}
(Store values of R1, R2, R3 at address in R0) | Example:
1
2
LDR R0, [R1] // Load value from memory address in R1 into R0
STR R0, [R2] // Store the value of R0 into the memory address in R2
The LDR and STR instructions are the most common load/store operations in ARM. LDM and STM are used for bulk data transfer between multiple registers and memory.
Branching Instructions
Branching instructions control the flow of execution, allowing the program to jump to different locations in the code, either conditionally or unconditionally. These are essential for implementing loops, conditionals, and function calls.
|Instruction|Description|Example| |—|—|—| |B|Unconditional branch (jump to a label).|B target
(Jump to target
label)| |BL|Branch with link (used for function calls). Saves the return address in the Link Register (LR).|BL my_function
(Call my_function
)| |BX|Branch to an address in a register, often used for function returns.|BX LR
(Return from function, jump to address in LR)| |BLX|Branch with link and exchange the instruction set (ARM to Thumb or vice versa).|BLX R0
(Branch to address in R0 and link)| Example:
1
2
3
4
5
6
B loop_start // Jump to the label 'loop_start'
// Function Call
BL function // Call 'function', return address saved in LR
BX LR // Return to the address stored in LR
Branching instructions, like B and BL, are key to controlling program flow and implementing loops and function calls. The BX and BLX instructions enable switching between ARM and Thumb modes, which are essential for performance optimization on ARM processors.
Stack Operations
ARM provides instructions for manipulating the stack, a special memory region used for function calls, local variables, and storing return addresses.
Instruction | Description | Example |
---|---|---|
PUSH | Push one or more registers onto the stack. Typically used to save register values before a function call. | PUSH {R0, R1, R2} (Push R0, R1, and R2 onto the stack) |
POP | Pop one or more registers from the stack. Typically used to restore register values after a function call. | POP {R0, R1} (Pop R0 and R1 from the stack) |
Example: Moving a 32-bit Value using LSL
1
2
3
mov r0, #0x1234 // Load the lower 16 bits into r0
lsl r0, r0, #16 // Shift r0 left by 16 bits to make room for the upper 16 bits
orr r0, r0, #0x5678 // Combine with the upper 16 bits using OR