# Memory-mapped I/O

*Talking to devices with LOAD and STORE*

Memory-mapped I/O connects a peripheral's control and data registers to specific memory addresses, so a CPU reads and writes devices with the same LOAD and STORE instructions it uses for RAM, needing no special I/O opcodes.

Group: Processor
URL: https://digiwleea.wleeaf.dev/learn/memory-mapped-io/

Your [CPU](https://digiwleea.wleeaf.dev/learn/cpu/) knows how to read and write [RAM](https://digiwleea.wleeaf.dev/learn/ram/) with `LOAD` and `STORE`. But a real computer must also talk to the outside world: read a button, light an LED, send a byte to a screen. **Memory-mapped I/O** is the elegant trick that needs no new instructions: it puts a device's registers at reserved **memory addresses**, so writing to that address drives the device and reading from it samples the device.

## Addresses that are not RAM

On the [datapath](https://digiwleea.wleeaf.dev/learn/datapath/), an address on the bus normally selects a RAM cell. Memory-mapped I/O carves out a few addresses and wires them to a **peripheral** instead. Say address `0xF0` is connected to an LED register: `STORE 0xF0` does not write RAM, it latches the accumulator's bits into that register, and the LEDs light accordingly. Read address `0xF1` and the bus returns a switch's current state instead of a stored byte. The CPU cannot tell the difference; to it, everything is just addresses.

An **address decoder** on the bus is what makes this work: it watches the address lines and routes the access to RAM for most addresses but to a device for the reserved ones. That is the same [decoder](https://digiwleea.wleeaf.dev/learn/decoder/) idea that picks a register, now picking *which chip* the address belongs to.

The analogy: a mailbox wall where most slots hold letters (RAM), but a few slots are actually chutes connected to machines, drop a note in slot 240 and a bell rings elsewhere. You use the same act (putting mail in a slot) whether you are storing a letter or ringing the bell; only where the slot leads differs.

> **WARN:** **Common mistakes.** A memory-mapped address is **not** ordinary storage: reading it may return live device state that changes on its own, and writing it may trigger an action rather than just save a value (so reading back what you wrote is not guaranteed). Those addresses must be excluded from normal RAM use, or a program will overwrite a device by accident. The alternative approach, **port-mapped I/O**, uses separate `IN`/`OUT` instructions and a distinct address space; memory-mapped I/O is simpler and needs no extra opcodes.

**Q (Try it):** How can a STORE instruction light an LED without adding a new opcode to the CPU?

**A:** By memory-mapping the LED. The LED's register is wired to a reserved address (say `0xF0`) through an address decoder on the bus. Then `STORE 0xF0` sends the accumulator's bits to that register instead of to RAM, and the LEDs display them. The CPU runs its ordinary `STORE`; only the decoder's routing makes the address a device rather than memory, so no new instruction is needed.

### FAQ

**Q:** What is memory-mapped I/O?

**A:** Memory-mapped I/O connects a peripheral's registers to specific memory addresses, so the CPU reads and writes devices with the same [LOAD and STORE](https://digiwleea.wleeaf.dev/learn/machine-code/) instructions it uses for [RAM](https://digiwleea.wleeaf.dev/learn/ram/). No special I/O opcodes are required; an address decoder routes reserved addresses to devices instead of memory.

**Q:** What is the difference between memory-mapped and port-mapped I/O?

**A:** **Memory-mapped I/O** places devices in the normal address space and uses ordinary load/store instructions. **Port-mapped I/O** gives devices a separate address space accessed with dedicated `IN`/`OUT` instructions. Memory-mapped is simpler and needs no extra opcodes, so most modern architectures use it.

**Q:** How does the CPU know an address is a device and not RAM?

**A:** An address [decoder](https://digiwleea.wleeaf.dev/learn/decoder/) on the bus watches the address lines and routes most addresses to RAM but the reserved ones to peripherals. The CPU itself does not distinguish them; to it, a device register is just another address on the bus.

> **KEY:** Memory-mapped I/O is possible precisely because our machine is [von Neumann](https://digiwleea.wleeaf.dev/learn/von-neumann-harvard/): everything, RAM and devices alike, hangs off the one shared bus and answers to an address. It is how the CPU you built reaches beyond its own memory into the real world.
