ARM Architecture
ARM processors power almost every phone and most microcontrollers. Learn the ARM RISC philosophy, profiles (Cortex-A, R, M), register file (R0–R15, CPSR/xPSR), load/store architecture, Thumb-2 instructions, condition codes, the AAPCS calling convention, pipelines, and ARM assembly examples.
ARM licenses its processor designs to chip makers, so billions of cores ship each year — from tiny Cortex-M0 sensors to Apple and Qualcomm application processors. Its energy efficiency comes from a clean RISC design.
An analogy
ARM is like a well-organised workshop where every tool must be brought to the bench (registers) before use — no working directly in the storeroom (memory). That rule keeps work fast and predictable.
Profiles
Cortex-A (application: Linux/Android, MMU, high performance), Cortex-R (real-time: automotive, storage controllers, lockstep safety), Cortex-M (microcontrollers: low power, deterministic interrupts).
Instruction set
32-bit ARM (A32), compact Thumb/Thumb-2 (T32, mixed 16/32-bit) used by Cortex-M, and 64-bit A64 in ARMv8-A. Many instructions can set flags (S suffix) and execute conditionally (IT blocks in Thumb).
Modes and exceptions
Cortex-M has Thread and Handler modes, MSP/PSP stacks, and the NVIC with automatic register stacking on interrupt entry. Cortex-A has exception levels EL0–EL3 for user, OS, hypervisor and secure monitor.
Microarchitecture
Pipelines from 2–3 stages (M0) to deep out-of-order (A7x/X). big.LITTLE mixes efficient and fast cores. Extensions: DSP and FPU (M4/M7), Helium/M-Profile Vector (M55), NEON/SVE (A-class), TrustZone security.
Formulas
- Load/store:
Only LDR/STR access memory; ALU ops use registers - Calling convention (AAPCS):
Args R0–R3, return R0, callee saves R4–R11 - Performance:
DMIPS = (DMIPS/MHz) × f_MHz
Worked example: Performance estimate
Given: Cortex-M4 ≈ 1.25 DMIPS/MHz at 168 MHz
Find: DMIPS.
- 1.25 × 168 = 210 DMIPS
Answer: ≈ 210 DMIPS
Worked example: Load/store
Given: Increment a variable in memory at address in R0
Find: Instructions.
- LDR R1, [R0]
- ADDS R1, R1, #1
- STR R1, [R0]
Answer: 3 instructions (no memory-to-memory ALU ops)
Sum an array in ARM Thumb-2 assembly
.syntax unified
.thumb
.global sum_array
@ uint32_t sum_array(const uint32_t *p, uint32_t n);
@ R0 = p, R1 = n, result in R0
sum_array:
movs r2, #0 @ sum = 0
cbz r1, done @ if n == 0 return 0
loop:
ldr r3, [r0], #4 @ r3 = *p; p += 4 (post-index)
adds r2, r2, r3 @ sum += r3
subs r1, r1, #1 @ n--
bne loop @ repeat while n != 0
done:
mov r0, r2 @ return sum
bx lrArguments arrive in R0/R1 per AAPCS; post-indexed LDR loads and advances the pointer in one instruction; BX LR returns. A C compiler generates almost the same code.
Common mistakes
- Wrong: Expecting ALU ops directly on memory. — Right: Load into registers first.
- Wrong: Ignoring calling-convention registers. — Right: Save R4–R11 if a function uses them.
Applications
- Smartphones: Cortex-A clusters with GPUs and NPUs.
- Automotive: Cortex-R in brakes and airbags.
- IoT & wearables: Cortex-M in sensors and watches.
Key takeaways
- RISC, load/store, 16 registers.
- Profiles: A, R, M.
- Thumb-2 for compact code.
- AAPCS: R0–R3 args, R0 return.
Going further
- TrustZone: Secure and non-secure worlds.
- NEON/SVE: SIMD vector processing.
- Memory model: Weak ordering and barriers (DMB, DSB).