← Pointers and MemoryC PROGRAMMING 1.2.H

Memory Layout & MMIO Patterns

The five memory segments, where variables actually live, the MMIO pointer pattern, register read-modify-write through volatile.

StatusCollected
NotesChapter test: 3/5 + 2/2 extra

Four pieces, and this is the payoff chapter for everything in 1.2 — the actual pattern used to read and write a hardware register from C.

The five segments

SegmentWhat lives there
Textthe compiled machine code itself
Initialized dataglobals and statics with an explicit initial value
BSSglobals and statics that default to zero
Heapmalloc'd memory, grows upward
Stacklocal variables and function call frames, grows downward

The MMIO pointer pattern

#define GPIO_BASE 0x40020000
volatile uint32_t *gpio_reg = (volatile uint32_t *)GPIO_BASE;

*gpio_reg = 0x1;                 /* write the register */
uint32_t status = *gpio_reg;     /* read the register */

A hardware register is just a fixed memory address — cast that address to a pointer, mark it volatile so the compiler never caches or reorders the access, and dereferencing it reads or writes the actual hardware.

Read-modify-write

*gpio_reg |= (1 << 3);    /* set bit 3, leave the rest alone */
*gpio_reg &= ~(1 << 3);   /* clear bit 3, leave the rest alone */

Setting a single bit without disturbing the others is the pattern that shows up in essentially every register access in real driver code — OR to set, AND-with-NOT to clear, and volatile making sure the compiler doesn't decide the read is redundant and skip it.

Notes from readers

Comments — via GitHub