The Process Abstraction: Address Space, Registers, PC
What This Concept Is
A process is what a running program looks like from the outside. Concretely, it bundles:
- an address space: code (
.text), initialized data, BSS, heap, and stack regions - registers, including the program counter (
PC) and the stack pointer (SP) - open-file state: file descriptor table, current working directory, umask
- kernel-owned state: PID, parent PID, credentials, signal mask, scheduling class
The operating system gives every running program the illusion of owning the CPU and memory. The process abstraction is the hole through which that illusion is maintained.
Why It Matters Here
Every later concept in this module is defined relative to the process:
- scheduling decides which process's registers get loaded next
forkandexecare operations on the state above, not on source code- a context switch is literally "save this state and load that state"
- threads share some of this state and isolate the rest
If the first picture is blurry, every later picture built on top of it is wrong.
Concrete Example
Suppose you run:
./a.out
After the shell's exec, the kernel has created a process whose address space looks roughly like:
0xffff... ┌────────────────────┐
│ kernel (inaccessible from user mode)
0x7fff... ├────────────────────┤
│ stack grows ↓
│ (locals, return addresses)
│
│
│ heap grows ↑
│ (malloc'd memory)
├────────────────────┤
│ .bss (zero-initialized globals)
│ .data (initialized globals)
│ .text (machine code)
0x00400000 └────────────────────┘
The PC starts at _start in .text. SP starts near the top of the stack region. When you call main, SP moves down. When you malloc, the heap grows up. These two grow toward each other and must not meet.
Common Confusion / Misconception
"A process is its code." No. Two processes can share identical code (.text mapped shared on Linux), yet be independent processes with different heaps, different file descriptors, and different execution progress. The process is the running instance, not the program binary.
Also: an address space is virtual. Two processes can both think they own address 0x400000, and the MMU maps those to different physical addresses. Module 2 picks this apart; here it is enough to know the addresses you see are per-process.
How To Use It
When reasoning about any system-level question, ask:
- Which process owns this state?
- Is that state in user space (part of the address space) or in kernel space (part of the PCB)?
- What would have to be saved or invalidated if this process were switched out right now?
Answer these three questions and most "which thread sees what" or "why did the file handle go away" questions resolve themselves.
Check Yourself
- Name at least six distinct pieces of state the OS must track per process.
- Which of those pieces live in the process's own address space, and which live in kernel memory?
- Why can two processes run the same program
a.outwithout interfering?
Mini Drill or Application
For each scenario, list what state is new, what is inherited, and what is overwritten:
- The shell
forks a child to runls. - The child calls
execve("/bin/ls", ...). lsfinishes and the shellwaits for it.
If you cannot answer in one sentence per scenario, reread the concrete example.