ARM Cortex-M Architecture | Comprehensive Study Guide
ARM Cortex-M Architecture
Comprehensive Study Guide
Memory Maps • Bit Banding • Bus Systems • Exception Handling • Thumb ISA • Addressing Modes
Page 1 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
1. Memory Map of the Cortex-M Processor
The ARM Cortex-M processor implements a fixed, linear 32-bit address space of 4 GB (0x00000000 –
0xFFFFFFFF). Unlike earlier Harvard-strictly-separated architectures, Cortex-M uses a unified memory
model that allows both code and data to reside anywhere, while still being optimised for code fetching
via separate I-Code and D-Code buses. The memory map is architecturally defined, meaning every Cortex-
M device — regardless of vendor — places its regions at identical base addresses. This consistency
dramatically simplifies software portability.
1.1 Memory Map Diagram
0xFFFFFFFF ┌────────────────────────────────┐
│ Vendor-Specific (0.5 GB) │ Implementation-defined
0xE0100000 ├────────────────────────────────┤
│ Private Peripheral Bus (PPB) │ SCS, NVIC, SysTick, MPU
0xE0000000 ├────────────────────────────────┤
│ External Device (1 GB) │ Non-cached peripherals
0xA0000000 ├────────────────────────────────┤
│ External RAM (1 GB) │ External memory
0x60000000 ├────────────────────────────────┤
│ Peripheral (0.5 GB) │ APB/AHB peripherals
0x40000000 ├────────────────────────────────┤
│ SRAM (0.5 GB) + Bit-band alias │ On-chip SRAM
0x20000000 ├────────────────────────────────┤
│ Code (0.5 GB) + Bit-band alias │ Flash, ROM, ITCM
0x00000000 └────────────────────────────────┘
1.2 Region-by-Region Breakdown
Code Region (0x00000000 – 0x1FFFFFFF) — 512 MB
This region is the primary instruction-fetch area and is connected to the dedicated I-Code and D-Code
buses. Flash memory, ROM, ITCM (Instruction Tightly Coupled Memory), and boot ROM are mapped here.
The processor can also fetch data from this region using the D-Code bus. The lower 1 MB (0x00000000 –
0x000FFFFF) holds the vector table at reset.
Bit-band capability: A 1 MB sub-region (0x00000000 – 0x000FFFFF) is bit-band capable, with its alias at
0x02000000 – 0x03FFFFFF.
SRAM Region (0x20000000 – 0x3FFFFFFF) — 512 MB
On-chip SRAM, stack, heap and run-time data reside here. The System bus services this region. Like the
Code region, the first 1 MB (0x20000000 – 0x200FFFFF) is bit-band capable; its alias is at 0x22000000 –
0x23FFFFFF. Code can also execute from SRAM if needed.
Peripheral Region (0x40000000 – 0x5FFFFFFF) — 512 MB
On-chip peripherals (GPIO, UART, SPI, TIM, ADC, etc.) are memory-mapped into this region. The APB and
AHB peripheral buses feed into it. The first 1 MB (0x40000000 – 0x400FFFFF) is bit-band capable, with
Page 2 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
alias at 0x42000000 – 0x43FFFFFF. Write operations to peripheral registers in this region are non-buffered
by default on Cortex-M0/M0+ but may be buffered on Cortex-M3/M4.
External RAM (0x60000000 – 0x9FFFFFFF) — 1 GB
External SDRAM, PSRAM, or NAND flash connected through the Flexible Memory Controller (FMC/FSMC)
maps here. Cacheable and non-cacheable sub-divisions allow MPU-controlled caching policies. This region
is accessed via the System bus.
External Device (0xA0000000 – 0xDFFFFFFF) — 1 GB
External devices such as external peripherals, LCD controllers, and Ethernet MACs that must not be cached
or reordered are mapped here. This region is always treated as Device or Strongly Ordered memory in the
ARM memory ordering model.
Private Peripheral Bus — PPB (0xE0000000 – 0xE00FFFFF)
This 1 MB region is accessible only in privileged mode and contains the processor's own internal resources:
• Instrumentation Trace Macrocell (ITM): 0xE0000000
• Data Watchpoint and Trace (DWT): 0xE0001000
• Flash Patch and Breakpoint (FPB): 0xE0002000
• System Control Space (SCS) including NVIC, SCB, SysTick, MPU: 0xE000E000
• CoreSight Trace Port Interface Unit (TPIU): 0xE0040000
Vendor-Specific (0xE0100000 – 0xFFFFFFFF)
Silicon vendors may place vendor-specific debug, EEPROM emulation, and other proprietary logic here.
1.3 Memory Attributes and Access Types
Attribute Description Example Usage
Normal CPU can reorder and cache accesses Flash, SRAM, external RAM
Device Access order preserved; no On-chip peripherals
speculation
Strongly Ordered All accesses in program order; global External device region
visibility guaranteed
Shareable Coherency maintained between Shared SRAM in multi-core
multiple bus masters
Execute Never (XN) Instruction fetch from this region Peripheral region
causes fault
Page 3 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
2. Bit Banding — Atomic Bit Manipulation
Bit banding is a memory-access technique unique to the ARM Cortex-M3 and M4 (not available on
M0/M0+) that allows individual bits in specific memory regions to be read or written using full 32-bit word
accesses to an expanded alias region. The critical advantage is atomicity: reading or writing a bit-band
alias address is a single indivisible bus transaction, eliminating the classic read-modify-write race
condition.
2.1 Concept and Formula
Two regions support bit banding:
• SRAM bit-band region: 0x20000000 – 0x200FFFFF (1 MB of actual SRAM)
• SRAM bit-band alias: 0x22000000 – 0x23FFFFFF (32 MB alias — each word = 1 bit)
• Peripheral bit-band region: 0x40000000 – 0x400FFFFF
• Peripheral bit-band alias: 0x42000000 – 0x43FFFFFF
The formula to compute the alias address for a given bit is:
Alias_Address = Alias_Base + (Byte_Offset × 32) + (Bit_Number × 4)
Where:
• Alias_Base = 0x22000000 (SRAM) or 0x42000000 (Peripheral)
• Byte_Offset = target address − bit-band region base
• Bit_Number = 0 (LSB) to 7 (MSB)
2.2 Worked Example — UART Status Register
Suppose a UART status register sits at 0x40013000 (inside the peripheral bit-band region). Bit 7 is the
Transmit Data Register Empty (TXE) flag. We want to poll only that bit without disturbing others.
// C example: atomic read of bit 7 in UART_SR at 0x40013000
#define UART_SR 0x40013000UL
#define PERIPH_BB_BASE 0x42000000UL
#define PERIPH_BASE 0x40000000UL
// Formula: alias = BB_BASE + (byte_offset * 32) + (bit * 4)
#define BB_ALIAS(addr, bit) \
(PERIPH_BB_BASE + ((addr - PERIPH_BASE) << 5) + ((bit) << 2))
volatile uint32_t *txe_alias =
(volatile uint32_t *) BB_ALIAS(UART_SR, 7);
// Atomic read: returns 0 or 1, no masking needed
while (*txe_alias == 0); // wait until TXE = 1
UART_DR = 'A'; // send character
Page 4 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
Without bit banding the same task requires:
while ((*(volatile uint32_t*)UART_SR & (1 << 7)) == 0); // non-atomic
The non-atomic version performs three bus operations: Load → AND → Branch. In an interrupt-driven
system, an ISR could modify the register between the Load and the Branch, creating a race condition. The
bit-band alias collapses this to a single Load, which is inherently atomic.
2.3 Atomic Write Example — GPIO Pin
Set GPIO pin 5 of GPIOB_ODR (0x40020414) high, atomically:
#define GPIOB_ODR 0x40020414UL
volatile uint32_t *pin5 =
(volatile uint32_t *) BB_ALIAS(GPIOB_ODR, 5);
*pin5 = 1; // Atomic set — only bit 5 changes
*pin5 = 0; // Atomic clear
The hardware translates the word write to the alias into a read-modify-write cycle internally on the AHB
bus in a single locked transaction. Software never sees the intermediate state.
2.4 Bit Banding Summary Table
Property Without Bit Banding With Bit Banding
Operations 3 (Load, OR/AND, Store) 1 (Store to alias)
Atomicity Not atomic Atomic (single bus
transaction)
Interrupt safety Requires disable/enable IRQ Inherently safe
Code size Slightly larger (mask Smaller
constant)
Availability All Cortex-M Cortex-M3, M4 only
Page 5 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
3. Cortex-M Processor Block Diagram
3.1 Block Diagram
┌─────────────────────────────────────────────────────┐
│ Cortex-M Core │
│ ┌────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ Registers │ │ ALU / FPU │ │ Control │ │
│ │ R0-R15 │ │ 32-bit ops │ │ Logic │ │
│ └────────────┘ └──────────────┘ └─────────────┘ │
│ │ │ │ │
│ ┌──────────────────────────────────────────────┐ │
│ │ AHB-Lite Bus Matrix │ │
│ └────────┬──────────────┬───────────────┬──────┘ │
└───────────│──────────────│───────────────│──────────┘
│ │ │
┌───────────▼─┐ ┌─────────▼──┐ ┌────────▼────────┐
│ I-Code Bus │ │ D-Code Bus │ │ System Bus │
│ (Fetch) │ │ (Data/Dbg) │ │ (Periph/SRAM) │
└─────────────┘ └────────────┘ └─────────────────┘
3.2 Component Descriptions
3.2.1 Processor Core (CPU)
The core is a 32-bit RISC engine that implements the ARMv7-M (Cortex-M3/M4) or ARMv6-M (Cortex-
M0/M0+) ISA. It contains:
• Register file: 16 general-purpose 32-bit registers (R0–R15). R13 = Stack Pointer (SP), R14 = Link
Register (LR), R15 = Program Counter (PC).
• ALU: Performs all arithmetic, logical, shift, and comparison operations in a single clock cycle.
• FPU (Cortex-M4/M7 only): Hardware single-precision (M4) or double-precision (M7) IEEE 754
floating-point unit.
• Control logic: Manages the pipeline, exception entry/exit, sleep modes, and instruction decode.
• 3-stage pipeline (M0/M3): Fetch → Decode → Execute. M4 has a shorter pipeline with branch
prediction.
3.2.2 NVIC — Nested Vectored Interrupt Controller
The NVIC is tightly coupled to the CPU core and provides low-latency, deterministic interrupt handling.
Key features:
• Supports up to 240 external interrupts (implementation-defined, typically 16–64).
• 8 programmable priority levels (M0/M0+) or up to 256 levels (M3/M4).
• Supports interrupt pre-emption, tail-chaining (back-to-back ISRs without full context save), and
late-arriving interrupt optimisation.
• Tail-chaining reduces ISR-to-ISR latency to as little as 6 cycles.
3.2.3 SysTick Timer
Page 6 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
A 24-bit auto-reload down-counter clocked from either the processor clock or a reference clock.
Universally used as the OS tick timer (FreeRTOS, RTX, etc.) because it is part of the architectural
specification and exists on every Cortex-M device.
3.2.4 Memory Protection Unit (MPU)
An optional but commonly included unit that defines up to 8 independently configurable memory regions
with access permissions (privileged/unprivileged read/write/execute). The MPU enforces isolation
between RTOS tasks, protecting the kernel from faulty application code.
3.2.5 AHB-Lite Bus Matrix
Acts as the internal crossbar switch routing transactions from the CPU to the correct external bus.
Arbitrates between I-Code, D-Code, and System bus initiators and peripheral targets. AHB-Lite is a
simplified subset of AMBA AHB without split/retry support, suitable for single-master systems.
3.2.6 Debug Subsystem (CoreSight)
Includes: Flash Patch & Breakpoint (FPB) for up to 8 hardware breakpoints, Data Watchpoint & Trace
(DWT) for 4 watchpoints and cycle counting, Instrumentation Trace Macrocell (ITM) for printf-style debug
output via SWO, Embedded Trace Macrocell (ETM, optional) for full instruction trace.
3.2.7 Wake-Up Interrupt Controller (WIC)
An optional power-gating controller that keeps a minimal interrupt-detection circuit powered when the
main core is fully clock-gated (deep sleep). Allows the core to wake instantly without software polling.
Page 7 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
4. ARM Instruction Set vs Thumb Instruction Set
4.1 Historical Background
The original ARM instruction set (now called A32) uses fixed 32-bit wide instructions aligned to 4-byte
boundaries. ARM introduced the Thumb ISA in ARMv4T as a re-encoded 16-bit subset to improve code
density for embedded systems constrained by narrow 8/16-bit memory buses and limited flash storage.
Thumb-2 (introduced in ARMv6T2) blends 16-bit and 32-bit instructions in a single execution state, giving
code-density close to 16-bit Thumb with performance close to full ARM.
4.2 Comparison Table
Feature ARM (A32) Thumb (T16) Thumb-2 (T32)
Instruction width 32-bit fixed 16-bit fixed 16-bit and 32-bit mixed
ISA generation ARMv4+ ARMv4T+ ARMv6T2+ (Cortex-
M3/M4)
Available on Cortex-M No (except M- Yes (M0, M0+) Yes (M3, M4, M7)
profile
assembly)
Code density Baseline ~30% smaller ~10% smaller than ARM
than ARM
Performance Highest (all ops Slightly lower Close to ARM
1 cycle) (more
instructions)
Conditional execution All instructions Only branches IT block for 4 instr
(B{cond})
Barrel shifter in data-proc Yes (any Limited (shift Yes (full like ARM)
operand) instr only)
Register access Full R0–R15 Mostly R0–R7 Full R0–R15
(Lo regs)
Load/Store multiple LDM/STM (any PUSH/POP (R0- LDMIA/STMIA extended
reg list) R7, LR/PC)
Multiply MUL, MLA, MUL (32×32→32 Full multiply set
UMULL… only)
Floating-point VFP extension Not available VFP/NEON (M4 with FPU)
State switch BX, BLX BX, BLX BX, BLX
4.3 Instruction Encoding Examples
4.3.1 ARM 32-bit Encoding (A32)
Page 8 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
31 28 27 26 25 24 21 20 19 16 15 12 11 0
┌─────┬──┬──┬──┬────┬──┬─────┬─────┬────────────┐
│Cond │00│I │ │Opc │S │ Rn │ Rd │ Operand2 │
└─────┴──┴──┴──┴────┴──┴─────┴─────┴────────────┘
Example: ADD R1, R2, R3 → E0821003 (hex)
4.3.2 Thumb 16-bit Encoding (T16)
15 11 10 8 7 6 5 3 2 0
┌──────┬────┬───┬───┬────┬────┐
│ 0001 1│Opc│ Rm │ Rn │ Rd │
└──────┴────┴───┴───┴────┴────┘
Example: ADDS R1, R2, R3 → 18D1 (hex, 16-bit)
4.3.3 Thumb-2 IT Block for Conditional Execution
IT EQ ; If-Then block: next instr executes if Z=1
ADDEQ R0, R0, #1 ; executed only if Z flag set
ITEE GT ; If-Then-Else-Else: cond, !cond, !cond
ADDGT R0, R0, #10
SUBLE R0, R0, #5
SUBLE R0, R0, #2
4.4 Code Density Illustration
The same C expression result = a + b + c; compiled to each ISA:
ARM (A32): LDR R0,[R4] ; 4 bytes
LDR R1,[R5] ; 4 bytes
LDR R2,[R6] ; 4 bytes
ADD R0,R0,R1 ; 4 bytes
ADD R0,R0,R2 ; 4 bytes → 20 bytes total
Thumb (T16): LDR R0,[R4] ; 2 bytes
LDR R1,[R5] ; 2 bytes
LDR R2,[R6] ; 2 bytes
ADDS R0,R0,R1 ; 2 bytes
ADDS R0,R0,R2 ; 2 bytes → 10 bytes total
Page 9 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
5. ARM Cortex-M Architecture — Major Components
5.1 Register Set
Cortex-M has 16 32-bit programmer-visible registers:
Register Name Role
R0–R7 Low registers General purpose; fully accessible by all 16-bit
Thumb instructions
R8–R12 High registers General purpose; require 32-bit Thumb
instructions to access
R13 (SP) Stack Pointer Two banked copies: MSP (Main SP, kernel) and
PSP (Process SP, tasks)
R14 (LR) Link Register Stores return address on BL/BLX; EXC_RETURN
value in ISRs
R15 (PC) Program Counter Points to current+4 (pipeline); writes cause
branches
xPSR Program Status Reg Combines APSR (flags N,Z,C,V,Q), IPSR (current
exception#), EPSR (Thumb T bit)
PRIMASK Priority Mask Bit 0 set → disables all configurable exceptions
(global IRQ off)
FAULTMASK Fault Mask Bit 0 set → disables all exceptions except NMI
BASEPRI Base Priority Masks interrupts at or below a given priority level
CONTROL Control Register Selects active SP (MSP/PSP) and privilege level
5.2 Pipeline
Cortex-M3/M4 uses a 3-stage pipeline: Fetch (instruction read from memory), Decode (decode and
register read), Execute (ALU operation and memory access). The pipeline allows single-cycle throughput
for most instructions. Branch prediction is limited but the pipeline can be flushed and restarted in 1–2
cycles.
5.3 Exception Model and Privilege Levels
Cortex-M implements two privilege levels: Privileged (full register and resource access) and Unprivileged
(restricted, cannot write CONTROL, limited region access). The processor also operates in two modes:
Thread mode (normal execution) and Handler mode (ISR execution, always privileged).
5.4 Operating Modes Summary
Page 10 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
Mode Privilege SP Used When
Thread mode (privileged) Privileged MSP or PSP Main code with full
access
Thread mode Unprivileged PSP RTOS task code
(unprivileged)
Handler mode Always privileged MSP Any exception / ISR
Page 11 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
6. Bus Systems in Cortex-M Architecture
The Cortex-M bus architecture is based on AMBA AHB-Lite (Advanced High-performance Bus). Three
primary buses emerge from the core to allow simultaneous code fetch and data access — a modified
Harvard scheme that achieves high throughput while maintaining a unified address space.
6.1 I-Code Bus
Property Detail
Protocol AHB-Lite
Direction Read-only (instruction fetch)
Width 32-bit data, 32-bit address
Address range served 0x00000000 – 0x1FFFFFFF (Code region)
Purpose Fetches instructions from flash or ROM
Burst support Yes — sequential burst for pipeline fill
Simultaneous with D-Code? Yes — true parallel operation
The I-Code bus is dedicated to instruction fetching from the Code memory region. Because it is a separate
physical bus, the CPU can fetch the next instruction while the D-Code bus completes a data load —
providing genuine dual-bus bandwidth. On cache-miss or branch, the I-Code bus initiates a burst read to
refill the instruction buffer.
6.2 D-Code Bus
Property Detail
Protocol AHB-Lite
Direction Read / Write
Width 32-bit data, 32-bit address
Address range served 0x00000000 – 0x1FFFFFFF (Code region)
Purpose Data access (literals, constants) from Code region
Typical use LDR from literal pool in flash; also debug access
The D-Code bus handles data accesses (loads and stores) to the Code region. This is important because
ARM code commonly has literal pools — constant values embedded in the flash image near the code.
Page 12 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
Without a separate D-Code bus, a data load from flash would block instruction fetch. The debugger (DAP)
also uses this bus to read/write flash contents.
6.3 System Bus
Property Detail
Protocol AHB-Lite
Direction Read / Write
Width 32-bit data, 32-bit address
Address range served 0x20000000 – 0xDFFFFFFF (SRAM, Peripherals, External)
Purpose All SRAM and peripheral accesses
Arbitration Bus matrix for multiple masters (DMA + CPU)
The System bus carries all accesses to SRAM, on-chip peripherals, and external memory. When a DMA
controller is present, the bus matrix arbitrates between the CPU and DMA, typically granting DMA higher
priority during burst transfers to avoid SRAM latency spikes.
6.4 Additional Buses
6.4.1 Private Peripheral Bus (PPB)
A separate 32-bit AHB-AP (Advanced Peripheral Bus to Advanced High-performance) bridge gives the
processor access to its own internal debug and system control registers (NVIC, SCB, SysTick, MPU,
CoreSight). Only privileged code can access this bus.
6.4.2 AHB to APB Bridge
Slow peripherals (I2C, UART running at low MHz) are placed on an APB bus bridge off the AHB. APB is a
simpler, lower-power bus with no burst support. The bridge converts AHB transactions into APB
transactions, inserting wait states as needed.
6.5 Bus Priority and Arbitration
The AHB bus matrix resolves simultaneous access conflicts. Typical priority order: DMA transfers (burst) >
CPU D-Code (data) > CPU I-Code (instruction). The matrix supports concurrent transactions on
independent paths (e.g., CPU reading SRAM via System bus while DMA writes peripheral via a separate
path), maximising throughput.
Page 13 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
7. Exception Handling in ARM Cortex-M
7.1 Exception Types
Exception Name Priority Description
#
1 Reset −3 (highest) Executes on power-on or system reset;
initialises the device
2 NMI −2 Non-Maskable Interrupt; cannot be
disabled by software
3 HardFault −1 Catch-all for faults when specific
handler not enabled
4 MemManage Configurable MPU access violation or execute-never
region fetch
5 BusFault Configurable AHB bus error on instruction/data
transaction
6 UsageFault Configurable Undefined instruction, unaligned access,
divide by zero
11 SVCall Configurable Supervisor Call — RTOS system call gate
12 DebugMon Configurable Debug monitor for software breakpoints
14 PendSV Configurable Pendable service call — used for RTOS
context switch
15 SysTick Configurable System tick timer overflow — RTOS
scheduler tick
16–255 IRQ0–IRQ239 Configurable External peripheral interrupts (device-
specific)
7.2 Vector Table
The vector table is an array of 32-bit word entries in memory, starting at address 0x00000000 by default
(or wherever VTOR points). Each entry holds the 32-bit address of the corresponding handler (with the
LSB set to 1 to indicate Thumb mode). The first entry (offset 0) is special: it holds the initial Main Stack
Pointer value, not a handler address.
Address │ Vector Entry
──────────┼──────────────────────────────
0x00000000│ Initial Stack Pointer (MSP)
0x00000004│ Reset Handler address
0x00000008│ NMI Handler address
0x0000000C│ HardFault Handler address
0x00000010│ MemManage Handler address
0x00000014│ BusFault Handler address
Page 14 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
0x00000018│ UsageFault Handler address
0x0000001C│ Reserved
... │ ...
0x00000040│ SysTick Handler address
0x00000044│ IRQ0 (External Interrupt 0)
... │ IRQ1 ... IRQ239
Vector Table Offset Register (VTOR)
The VTOR register (SCB base + 0x08) allows the vector table to be relocated anywhere in the Code or
SRAM region (aligned to a 256-byte or 512-byte boundary, depending on the implementation). RTOS
kernels use this to install their own vector tables in RAM for dynamic handler registration.
7.3 Exception Entry Sequence
When an exception occurs, the hardware automatically performs a context save (called stacking) before
the ISR executes:
Exception occurs
│
▼
CPU pushes {xPSR, PC, LR, R12, R3, R2, R1, R0} onto stack
│
▼
NVIC reads Vector Table base (VTOR) + (Exception# × 4)
│
▼
Fetches handler address from vector table entry
│
▼
Jumps to ISR; LR = EXC_RETURN magic value
│
Handler executes ...
│
▼
BX LR (EXC_RETURN) → CPU pops saved context, resumes thread
Stack Frame (8 registers, 32 bytes)
SP+0: R0 (pre-exception value)
SP+4: R1
SP+8: R2
SP+12: R3
SP+16: R12
SP+20: LR (return address of interrupted code)
SP+24: PC (address of next instruction to run after return)
SP+28: xPSR (flags and exception number)
Page 15 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
If the FPU is active (Cortex-M4), an additional 18 registers (S0–S15, FPSCR, reserved) are optionally stacked
(lazy stacking avoids this until the ISR actually uses FP registers).
7.4 EXC_RETURN Values
EXC_RETURN Value Return to Stack used
0xFFFFFFF1 Handler mode MSP
0xFFFFFFF9 Thread mode MSP
0xFFFFFFFD Thread mode PSP
0xFFFFFFE1 Handler mode (FPU active) MSP
0xFFFFFFED Thread mode (FPU active) PSP
7.5 Tail-Chaining and Late Arriving
Tail-chaining: If another exception is pending when an ISR finishes, the CPU skips the full unstack-stack
sequence and jumps directly to the new ISR, saving up to 12 cycles. Late-arriving: If a higher-priority
exception arrives during the stacking phase of a lower-priority exception, the CPU re-vectors to the higher-
priority ISR without restarting the stack save.
Page 16 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
8. Thumb Instruction Programming
8.1 Data Processing Instructions
Instruction Syntax Operation Flags Updated
MOV MOV Rd, Rn/#imm Rd = Rn or #imm N, Z (16-bit), none
(32-bit no S)
MOVS MOVS Rd, #imm8 Rd = #imm8 N, Z, C
MVN MVN Rd, Rn Rd = NOT Rn N, Z
ADDS ADDS Rd, Rn, Rd = Rn + Rm/#imm3 N, Z, C, V
Rm/#imm3
SUBS SUBS Rd, Rn, Rd = Rn − Rm/#imm3 N, Z, C, V
Rm/#imm3
MULS MULS Rd, Rm, Rd Rd = Rd × Rm (32-bit result) N, Z
ANDS ANDS Rd, Rm Rd = Rd AND Rm N, Z
ORRS ORRS Rd, Rm Rd = Rd OR Rm N, Z
EORS EORS Rd, Rm Rd = Rd XOR Rm N, Z
BICS BICS Rd, Rm Rd = Rd AND NOT Rm N, Z
LSLS LSLS Rd, Rm, #shift Rd = Rm LSL #shift N, Z, C
LSRS LSRS Rd, Rm, #shift Rd = Rm LSR #shift N, Z, C
ASRS ASRS Rd, Rm, #shift Rd = Rm ASR #shift (sign N, Z, C
extend)
RORS RORS Rd, Rm Rd = Rd ROR Rm N, Z, C
RSBS RSBS Rd, Rn, #0 Rd = 0 − Rn (negate) N, Z, C, V
CMP CMP Rn, Rm/#imm8 Rn − Rm, discard result N, Z, C, V
CMN CMN Rn, Rm Rn + Rm, discard result N, Z, C, V
TST TST Rn, Rm Rn AND Rm, discard result N, Z
8.2 Memory (Load / Store) Instructions
Instruction Syntax Transfer
LDR LDR Rd, [Rn, #imm5<<2] Load 32-bit word from memory[Rn+imm5*4]
LDRH LDRH Rd, [Rn, #imm5<<1] Load 16-bit halfword, zero-extend
LDRB LDRB Rd, [Rn, #imm5] Load 8-bit byte, zero-extend
Page 17 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
Instruction Syntax Transfer
LDRSH LDRSH Rd, [Rn, Rm] Load 16-bit halfword, sign-extend
LDRSB LDRSB Rd, [Rn, Rm] Load 8-bit byte, sign-extend
STR STR Rd, [Rn, #imm5<<2] Store 32-bit word to memory
STRH STRH Rd, [Rn, #imm5<<1] Store lower 16 bits
STRB STRB Rd, [Rn, #imm5] Store lower 8 bits
LDR (lit) LDR Rd, =const Load 32-bit constant from literal pool
(pseudo-instruction)
LDM LDM Rn!, {reg-list} Load multiple words, Rn auto-increments
STM STM Rn!, {reg-list} Store multiple words, Rn auto-increments
PUSH PUSH {reg-list} PUSH registers onto stack (SP decremented)
POP POP {reg-list} POP registers from stack (SP incremented)
8.3 Branch Instructions
Instruction Syntax Description Range
B B label Unconditional branch ±2 KB (T16), ±16 MB
(T32)
B{cond} BEQ / BNE / BGT… Conditional branch on flags ±256 bytes (T16), ±1 MB
(T32)
BL BL label Branch with link (call subroutine) ±16 MB
BX BX Rm Branch and exchange (switch Any address
Thumb/ARM state)
BLX BLX Rm Branch, link, and exchange Any address
CBZ CBZ Rn, label Compare and branch if zero 0–126 bytes forward
(Thumb-2)
CBNZ CBNZ Rn, label Compare and branch if non-zero 0–126 bytes forward
(Thumb-2)
TBB TBB [Rn, Rm] Table branch byte — switch/case Calculated
(Thumb-2)
TBH TBH [Rn, Rm, LSL Table branch halfword (Thumb- Calculated
#1] 2)
8.4 System Instructions
Page 18 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
Instruction Description
SVC #imm8 Supervisor Call — triggers SVCall exception for RTOS system calls
BKPT #imm8 Software breakpoint — halts core and enters debug state
NOP No operation — pipeline padding or timing delay
WFI Wait For Interrupt — enters sleep until interrupt or debug event
WFE Wait For Event — enters sleep until event (SEV or interrupt)
SEV Send Event — wakes WFE on current or other core (SMP)
DSB Data Synchronisation Barrier — all memory accesses complete before next
instruction
DMB Data Memory Barrier — memory ordering constraint between accesses
ISB Instruction Synchronisation Barrier — flushes pipeline; ensures subsequent
fetches use new context
MRS Rd, SReg Move from Special Register to general register
MSR SReg, Rn Move from general register to Special Register
CPSID I Change Processor State: disable interrupts (set PRIMASK)
CPSIE I Change Processor State: enable interrupts (clear PRIMASK)
Page 19 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
9. Addressing Modes in ARM Processors
ARM processors support a rich set of addressing modes that specify how the effective address of an
operand is calculated. In Thumb/Thumb-2 the full set is available, though some modes have encoding
restrictions for 16-bit instructions.
9.1 Immediate Addressing
The operand is encoded directly inside the instruction word. No memory access is required to obtain the
value.
MOV R0, #42 ; R0 = 42 (decimal)
MOVS R1, #0xFF ; R1 = 255 (8-bit immediate in T16)
MOV.W R2, #0x12345678 ; R2 = 0x12345678 (Thumb-2 32-bit imm via MOVW+MOVT)
Thumb-2 (T32) encodes a 12-bit modified immediate using a rotation scheme that allows many common
constants to fit in 32-bit instructions. For arbitrary 32-bit values, two instructions are needed: MOVW
(lower 16 bits) and MOVT (upper 16 bits).
9.2 Register (Direct) Addressing
The operand is the content of a register. This is the fastest mode — no memory access at all.
MOV R1, R0 ; R1 = R0
ADDS R2, R0, R1 ; R2 = R0 + R1
CMP R3, R4 ; set flags based on R3 - R4
9.3 Register Indirect (Base Register) Addressing
The effective address is the value of a base register. The register holds the memory address; the
instruction accesses that location.
LDR R0, [R1] ; R0 = Memory[R1]
STR R2, [R3] ; Memory[R3] = R2
9.4 Register Indirect with Immediate Offset
The effective address is the sum of a base register and a small unsigned immediate offset. This is the most
common addressing mode for accessing structure fields and array elements.
LDR R0, [R1, #8] ; R0 = Memory[R1 + 8] (byte offset)
STRB R2, [R3, #1] ; Memory[R3 + 1] = low byte of R2
LDRH R4, [R5, #4] ; R4 = halfword at R5+4, zero-extended
Thumb-16 bit encoding allows offsets of 0–124 bytes (word access), 0–62 (halfword), 0–31 (byte). Thumb-
2 extends this to 12-bit unsigned (0–4095) or 8-bit signed (−128 to +127).
Page 20 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
9.5 Register Indirect with Register Offset
The effective address is the sum of two registers (optionally with a shift on the offset register in
ARM/Thumb-2). Useful for arrays where the index is in a register.
LDR R0, [R1, R2] ; R0 = Memory[R1 + R2]
LDR R0, [R1, R2, LSL #2] ; R0 = Memory[R1 + R2*4] (Thumb-2)
; e.g., R2 = array index, R1 = base address of int32 array
9.6 Pre-Indexed (Register Indirect with Pre-Increment/Decrement)
The base register is updated before the memory access. The final effective address is base ± offset, and
the base register is written back.
LDR R0, [R1, #4]! ; R1 = R1+4, then R0 = Memory[R1] (T32)
STR R2, [R3, #-8]! ; R3 = R3-8, then Memory[R3] = R2 (T32)
Thumb-16 does not directly support pre-indexed with write-back; this is a Thumb-2 (T32) feature. PUSH
uses pre-decrement of SP automatically.
9.7 Post-Indexed (Register Indirect with Post-Increment/Decrement)
The memory access uses the current base register value, then the base register is updated afterwards.
Ideal for sequential buffer scanning.
LDR R0, [R1], #4 ; R0 = Memory[R1], then R1 = R1+4 (T32)
STR R2, [R3], #-4 ; Memory[R3] = R2, then R3 = R3-4 (T32)
; Classic pattern to copy a buffer:
loop: LDR R0, [R1], #4 ; load and advance source
STR R0, [R2], #4 ; store and advance dest
SUBS R3, R3, #1
BNE loop
9.8 PC-Relative Addressing (Literal Pool)
The effective address is PC + a signed offset. Used to access constants (literal pool) embedded in the code
section. The assembler generates the offset automatically.
LDR R0, =0xDEADBEEF ; pseudo-instruction: places 0xDEADBEEF
; in literal pool; emits LDR R0,[PC,#offset]
LDR R1, MyConst ; label in .data / literal pool
ADR R2, MyTable ; R2 = PC + offset to MyTable
The ADR instruction forms PC-relative addresses without a memory load — the address itself is the result.
ADRP (AArch64) or ADR.W (Thumb-2) extend the range.
9.9 Stack Addressing (SP-Relative)
Special Thumb-16 encodings use SP as the implicit base register for stack operations.
Page 21 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
PUSH {R0-R3, LR} ; SP = SP - 20, stores 5 regs
POP {R0-R3, PC} ; restores 5 regs, PC = return addr
LDR R0, [SP, #12] ; load local variable at SP+12
STR R1, [SP, #4] ; store to stack frame slot
9.10 Summary of Addressing Modes
Mode Syntax (Thumb) Effective Typical Use
Address
Immediate MOV R0, #42 Operand = #42 Constants, initialisations
(no address)
Register ADD R0, R1, R2 Operand = Rn (no Arithmetic on registers
memory)
Register Indirect LDR R0, [R1] EA = R1 Pointer dereference
Base + Immediate LDR R0, [R1, #8] EA = R1 + 8 Struct field access
Offset
Base + Register Offset LDR R0, [R1, R2] EA = R1 + R2 Array indexing
Pre-indexed LDR R0, [R1, #4]! R1+=4; EA = R1 Iterator advance before
(writeback) load
Post-indexed LDR R0, [R1], #4 EA = R1; R1+=4 Buffer scan / copy loops
(writeback)
PC-Relative LDR R0, =val EA = PC + offset Literal pool constants
SP-Relative LDR R0, [SP, #12] EA = SP + 12 Local variables on stack
Page 22 of 23
ARM Cortex-M Architecture | Comprehensive Study Guide
End of Study Guide
ARM Cortex-M Architecture | Comprehensive Reference
Page 23 of 23