How does a running program see memory, and what is a virtual address space?
A process sees memory as one big private array of bytes, each picked out by a (virtual) address; the operating system quietly maps those addresses onto the real hardware.
* Each process sees its own private, flat byte array; the OS maps those virtual addresses onto the physical memory hierarchy. *
Rather than let programs touch physical RAM directly, the system hands each process its own virtual address space — conceptually a huge, flat array of bytes numbered 0x0000… upward. A program only ever names virtual addresses; it never sees where the data physically lives.
- Byte-addressable: every individual byte has its own address, so the smallest thing you can point at is one byte (this is why byte ordering, below, is even a question).
- Private per process: each program gets a separate space, so it can clobber its own data but cannot read or corrupt another process's — the isolation the OS enforces.
- Backed by a hierarchy: that flat array is an illusion built on registers → cache → RAM → disk; the program is shielded from the messy reality.
- Allocation is managed: the compiler and run-time system decide where each object (code, globals, stack, heap) sits within the single space.
Why it matters for reverse engineering: every address you see in a disassembly or a debugger is a virtual address into this per-process array — so the same byte offsets behave identically regardless of the physical memory underneath.
Go deeper:
Virtual address space (Wikipedia) — how the OS gives each process its own mapped byte array.