← 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.
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
| Segment | What lives there |
|---|---|
| Text | the compiled machine code itself |
| Initialized data | globals and statics with an explicit initial value |
| BSS | globals and statics that default to zero |
| Heap | malloc'd memory, grows upward |
| Stack | local 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