Het opslaan van alle gegevens in registers zou de meeste CPU's te ingewikkeld (en erg duur) maken. Daarom worden in registers meestal alleen de gegevens opgeslagen waar de CPU "op dit moment" mee bezig is. De rest van de door het programma gebruikte gegevens wordt opgeslagen in RAM (Random Access Memory). Behalve in microcontrollers wordt RAM meestal buiten de CPU opgeslagen in afzonderlijke chips.
Wanneer de CPU gegevens in het RAM wil lezen of schrijven, geeft hij een adres aan die gegevens. Elke byte in RAM heeft een geheugenadres. De grootte van de adressen is vaak gelijk aan de woordgrootte: Een 32-bits CPU gebruikt 32-bits adressen, enz. Kleinere CPU's, zoals 8-bits CPU's, gebruiken echter vaak adressen die groter zijn dan de woordgrootte. Anders zou de maximale programmalengte te kort zijn.
Omdat de grootte van de adressen beperkt is, is ook de maximale hoeveelheid geheugen beperkt. 32-bits processoren kunnen gewoonlijk slechts tot 4 GB RAM verwerken. Dit is het aantal verschillende bytes dat kan worden geselecteerd met behulp van een 32-bits adres (elk bit kan twee waarden hebben - 0 en 1 - en 232 bytes is 4 GB). Een 64-bits processor zou tot 16 EB RAM kunnen verwerken (16 exabytes, ongeveer 16 miljard GB, of 16 miljard miljard bytes). Het besturingssysteem kan het gebruik van kleinere hoeveelheden beperken.
De informatie die in het RAM wordt opgeslagen is meestal vluchtig. Dit betekent dat deze verdwijnt als de computer wordt uitgeschakeld.
Geheugenbeheereenheden (MMU's) en virtueel geheugen
Moderne CPU's maken vaak gebruik van een geheugenbeheereenheid (MMU). Een MMU is een onderdeel dat adressen van de CPU vertaalt naar (meestal) verschillende RAM-adressen. Bij gebruik van een MMU zijn de adressen die in een programma worden gebruikt (meestal) niet de "echte" adressen waar de gegevens zijn opgeslagen. Dit wordt virtueel (het tegenovergestelde van "echt") geheugen genoemd. Enkele van de redenen waarom het goed is om een MMU te hebben worden hier opgesomd:
- Een MMU kan het geheugen van andere programma's "verbergen" voor een programma. Dit wordt gedaan door geen adressen te vertalen naar de "verborgen" adressen terwijl het programma draait. Dit is goed omdat het betekent dat programma's het geheugen van andere programma's niet kunnen lezen en wijzigen, wat de veiligheid en stabiliteit ten goede komt. (Programma's kunnen elkaar niet "bespioneren", of "op elkaars tenen trappen").
- Veel MMU's kunnen sommige delen van het geheugen niet-schrijfbaar, niet-leesbaar of niet-uitvoerbaar maken (wat betekent dat code in dat deel van het geheugen niet kan worden uitgevoerd). Dit kan goed zijn om redenen van stabiliteit en veiligheid, maar ook om andere redenen.
- Met MMU's kunnen verschillende programma's verschillende "weergaven" van het geheugen hebben. Dit is handig in veel verschillende situaties. Zo zal het bijvoorbeeld altijd mogelijk zijn om de "hoofd"-code van een programma op hetzelfde (virtuele) adres te hebben zonder met andere programma's te botsen. Het is ook handig wanneer er veel verschillende stukken code (uit bibliotheken) zijn die door programma's worden gedeeld.
- MMU's zorgen ervoor dat code uit bibliotheken op verschillende adressen verschijnt telkens wanneer een programma wordt uitgevoerd. Dit is goed omdat het voor hackers moeilijker is om programma's slechte dingen te laten doen als zij niet weten waar dingen in het geheugen staan. Dit heet randomisatie van de adresruimte.
- Geavanceerde programma's en besturingssystemen kunnen trucs gebruiken met MMU's om te voorkomen dat gegevens tussen verschillende plaatsen in het geheugen moeten worden gekopieerd.