Process address space
The addresses a process uses and the addresses the memory sees: logical and physical address spaces, address binding at compile, load and execution time, the memory-management unit with base and limit registers, dynamic loading and linking, shared libraries, and how each process gets its own layout of code, data, heap and stack.
Why it exists
A program is written without knowing where in memory it will run. Its addresses must somehow turn into the real addresses of the machine, and different processes must be kept apart even though each believes it has the whole memory to itself. The idea that makes this possible is that the addresses a program generates (logical, or virtual, addresses) are different from the addresses the memory sees (physical addresses), with hardware translating between them for every reference. This page explains that separation, when the translation can be fixed, and how a process's address space is laid out; paging and segmentation then give the most important translation schemes.
Prerequisites
The layout of a C program's memory (text, data, bss, heap and stack) is described in C memory layout, and the contiguous-allocation setting in memory management basics.
Precise definitions
Logical (virtual) address. The address generated by the CPU when the process executes an instruction or accesses data. The set of all logical addresses a process can generate is its logical address space. With -bit addresses the logical address space has addresses.
Physical address. The address seen by the memory hardware (loaded into the memory address register). The set of physical addresses is the physical address space; with -bit physical addresses and byte addressing it has bytes at most.
Memory-management unit (MMU). The hardware that maps logical addresses to physical addresses at run time. The program only ever sees logical addresses; the physical addresses are never visible to it.
Address binding. Mapping the symbolic addresses in the source (variable and function names) to actual addresses. It can happen at three times:
| Binding time | What happens | Consequence |
|---|---|---|
| Compile time | the compiler knows where the program will be loaded and generates absolute code | the program must always be loaded at that address; to change it, recompile |
| Load time | the compiler generates relocatable code and the loader fixes the addresses when it loads the program | the program can be loaded anywhere, but once loaded it cannot be moved |
| Execution (run) time | binding is delayed until the program runs; the MMU translates every address | the process can be moved in memory while it runs; needs hardware support; used by general-purpose operating systems |
Logical and physical addresses are the same under compile-time and load-time binding, and differ under execution-time binding.
Base and limit registers. The simplest MMU. A base (relocation) register holds the physical address where the process starts; a limit register holds the size of its logical address space. For every address the CPU generates:
- if the logical address is at least the limit, trap to the operating system (an addressing error);
- otherwise the physical address is the logical address plus the base.
The legal logical addresses are . The registers can be loaded only by privileged instructions, so a process cannot change its own protection. Because each process has its own base and limit (saved and restored at a context switch), one process cannot reach another's memory, and moving a process only needs a new base value.
Dynamic loading. A routine is not loaded until it is called; unused routines never occupy memory. Static linking: the libraries are combined into the executable. Dynamic linking: linking is postponed until run time; a small stub finds the library routine, loading it if needed; the library can be shared by many processes (a shared library, a DLL) and updated without relinking every program.
The layout of a process's logical address space. From low addresses: text (code, read-only, shareable), initialised data, uninitialised data (bss), the heap (grows upward) and the stack (grows downward from the top), with a large unused gap between heap and stack. The kernel is usually mapped into a protected part of every process's address space (for example the top part on 32-bit systems), so a system call does not need to change the address space. The exact order and the addresses are system dependent and are often randomised for security. Each process has its own address space: the same logical address in two processes refers to different physical memory.
Swapping and address binding. A process swapped out can be brought back to a different place only if addresses are bound at execution time (swapping).
How it works
The animation is the base and limit MMU at work: base 14000, limit 3000. Addresses below 3000 are relocated; the address 3000 itself is not legal (the legal range is 0 to 2999), nor is 3250.
Base and limit registers: start
Translation computed, not typed| base | limit |
|---|---|
| 14000 | 3000 |
No address yet.
Step 0
The simplest protection: the process is in one contiguous block of memory. The hardware keeps a BASE (relocation) register and a LIMIT register. A logical address is legal only if it is LESS THAN the limit; the physical address is base + logical address. Here base = 14000 and limit = 3000, so the legal logical addresses are 0 to 2999.
Worked examples
EX 1Relocating with base and limit
EasyA process has base 14000 and limit 3000. Logical address 346 is legal (), physical address . Logical address 2999 gives 16999. Logical 3000 is illegal (the limit is exclusive: legal addresses are 0 to 2999): trap. If the operating system moves the process to start at 20000, only the base register changes; the program, which generated 346, keeps working, now reaching physical address 20346.
EX 2Two processes, one logical address
EasyA program computes the same address 346 in two different processes. Process A has base 14000 and limit 3000, process B has base 40000 and limit 1200. The physical addresses reached are 14346 and 40346: different memory, so neither sees the other's data. A C program shows the translation and the traps:
#include <stdio.h>
/* relocation: the MMU adds the base to every address the program generates, after checking it against the limit */
struct mmu { unsigned base, limit; };
static int translate(struct mmu m, unsigned logical, unsigned *physical) {
if (logical >= m.limit) return 0;
*physical = m.base + logical;
return 1;
}
int main(void) {
struct mmu a = {14000, 3000}, b = {40000, 1200};
unsigned p;
unsigned addrs[3] = {346, 1199, 2999};
for (int i = 0; i < 3; i++) {
printf("logical %4u: process A -> %s", addrs[i], translate(a, addrs[i], &p) ? "" : "trap");
if (translate(a, addrs[i], &p)) printf("%u", p);
printf("; process B -> ");
if (translate(b, addrs[i], &p)) printf("%u\n", p); else printf("trap\n");
}
/* the same logical address in two processes reaches different physical memory; the logical space of each is 0 .. limit - 1 */
printf("logical space of A: %u addresses, of B: %u addresses\n", a.limit, b.limit);
return 0;
}logical 346: process A -> 14346; process B -> 40346
logical 1199: process A -> 15199; process B -> 41199
logical 2999: process A -> 16999; process B -> trap
logical space of A: 3000 addresses, of B: 1200 addressesReading it. The last address, 2999, is legal for A and a trap for B, whose limit is 1200. Protection and relocation come from the same two registers.
EX 3Which binding time?
MediumA program for an embedded device is compiled to run at address 0x8000 and always loaded there: compile-time binding (absolute code). A program is compiled with all addresses relative to its start, and the loader adds the load address to each address constant when it loads the program; the program stays put once started: load-time binding. A program is loaded at one place, runs for a while, is compacted to another place while it is running, and keeps working: execution-time binding, which needs an MMU with a base register. A common question: "which scheme allows a process to be moved during execution?" Execution-time binding only. "Which schemes give identical logical and physical addresses?" Compile time and load time.
EX 4Sizes of the address spaces
MediumWith 32-bit logical addresses the logical address space is bytes GB, whatever the physical memory. A machine with 36-bit physical addresses can address GB. A process may have a logical address space larger than the physical memory (that is what virtual memory allows, virtual memory); it can never have a physical address space larger than . A question gives the number of bits of one and asks for the size of the other only when a mapping scheme (page size, frame size) ties them together.
EX 5Is this statement true?
GATE level"With execution-time binding, the logical and physical addresses of a variable are the same." False: the MMU maps them. "A process can change its base register to reach other processes' memory." False: loading the base and limit registers is privileged. "Dynamic linking makes the executable larger." False: it makes it smaller (the library code is not in it) and lets processes share one copy of the library. "The limit register holds the largest legal address." Usually false: it holds the size (the number of legal addresses), and the largest legal address is limit ; read how the question defines it. "Moving a process in memory under base-limit relocation needs the program to be recompiled." False: only the base register is updated.
Cheat box
Cheat box
- Logical (virtual) address: generated by the CPU. Physical address: seen by memory. The MMU maps them at run time.
- Binding: compile time (absolute, fixed place), load time (relocatable, cannot move after loading), execution time (MMU, can move while running).
- Base and limit: legal iff logical limit; physical base logical. Privileged registers; saved per process.
- Logical address space for -bit addresses; physical .
- Dynamic loading: load a routine when called. Dynamic linking: stub resolves at run time; libraries shared.
- Each process has its own address space (text, data, bss, heap up, stack down).
Traps and GATE patterns
Connections
Unlocks
Across subjects
Within this subject
Journeys that pass through here
The layout of text, data, heap and stack in a C program is traced from a real run in C memory layout. Base-and-limit hardware is the simplest of the translation schemes; paging replaces the single base with a table of frame numbers, and segmentation gives every segment its own base and limit. Because the logical space can exceed physical memory, virtual memory keeps only part of it in RAM.
PYQs
1 previous year question from your book. I re-solved each one myself (0 by running or simulating, 1 by reasoning only); the book's key is shown next to my answer. All PYQs
A computer system supports 32-bit virtual addresses as well as 32-bit physical addresses. Since the virtual address space is of the same size as the physical address space, the operating system designers decide to get rid of the virtual memory entirely. Which one of the following is true?
- (a)Efficient implementation of multi-user support is no longer possible
- (b)The processor cache organization can be made more efficient now
- (c)Hardware support for memory management is no longer needed
- (d)CPU scheduling can be made more efficient now
Self-check
Question 1
Base 5000, limit 800. What physical address does logical address 799 map to? And 800?
Show answerHide
799 is legal: . 800 is not below the limit: trap.
Question 2
Which binding scheme allows compaction while processes are running?
Show answerHide
Execution-time binding (with a relocation register).
Question 3
A machine has 40-bit physical addresses and a program has 32-bit logical addresses. What are the sizes of the two address spaces?
Show answerHide
Logical GB; physical up to TB.
Question 4
Why can two processes use the same logical address without conflict?
Show answerHide
Each process has its own mapping (its own base and limit, or page table), so the same logical address is translated to different physical addresses.
Revision card
One-screen revision
- Logical (CPU) vs physical (memory) addresses; MMU maps at run time.
- Binding: compile, load, execution time; only execution time lets a process move.
- Base and limit: legal iff logical limit; physical base logical.
- Dynamic loading and linking; shared libraries. Each process has its own address space.
References
- ·Silberschatz, Galvin, Gagne, Operating System Concepts, Chapter 9 Main Memory (background: basic hardware, address binding, logical versus physical address space, dynamic loading and linking)
- ·Tanenbaum and Bos, Modern Operating Systems, Chapter 3 Memory Management (a memory abstraction: address spaces)
- ·Stallings, Operating Systems: Internals and Design Principles, Chapter 7 Memory Management (memory management requirements: relocation, protection)
Verification
The relocation and limit translation in the animation is performed by a script (scripts/gen-os-mem-traces.py) and rechecked by tests/os-mem-traces.test.ts (an address is legal exactly when it is below the limit, and then the physical address is base plus the logical address); the C program on this page (npm run verify:c) performs the same translation for two processes. The classification of binding times and the loading and linking statements are textbook definitions and are not machine-checked. The layout of a real process (the order of text, data, heap and stack, and where the kernel is mapped) is system dependent; the page says so and refers to the C memory layout page, whose trace was produced by a real run. Textbook chapter titles are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand. No defect found. Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)