15 min read Foundations Lesson 06 of 12
Course 02 · Part 2 — Operating Systems & Execution

How a Program Runs

From the exact microsecond you double-click an application icon until a fully interactive window appears on your display, what happens beneath the surface? Follow the breathtaking lifecycle of a running program.

The Symphony Behind Double-Clicking

Whenever you want to launch an application on your computer, all you do is double-click an icon. Within seconds, the program springs to life on your monitor. From the outside, the interaction appears almost trivial:

Double-click ──► Application Running

Yet beneath that simple click lies a vast, synchronized engineering choreography—storage retrieval, binary parsing, memory space allocation, dynamic library linking, CPU thread scheduling, and hardware GPU composition. Today, we follow this transformation from start to finish.

1. Program vs. Process — Are They the Same?

One of the most foundational distinctions in systems engineering is: A Program and a Process are not the same thing!

Program

A Program is a passive, stored collection of bytes and instructions resting dormant on non-volatile media (SSD or HDD), such as Chrome.exe or /usr/bin/python3.

Passive entity on disk
Process

When the operating system loads that program into memory and assigns it active CPU cycles and runtime resources, it becomes an active, living Process.

Active entity with CPU/RAM resources

There is only one chrome.exe file residing on your SSD. However, when you launch three separate browser windows, the operating system creates three completely independent Processes in RAM!

2. The Genesis: User Action & Executable Lookup

The instant your finger clicks the physical mouse button twice:

1. Mouse Hardware → Dispatches electrical interrupt across USB bus
2. Mouse Driver → Converts signals into desktop coordinate events (X, Y)
3. Window Manager → Identifies a double-click hit on an application shortcut
4. OS Shell → Emits an execution launch request targeting the program's path

The operating system then resolves the target binary's file system path (such as C:\Program Files\App\app.exe on Windows or /usr/bin/app on Linux) and initiates the file open sequence.

3. What Is an Executable File?

An Executable is not an arbitrary dump of binary bytes. It is a highly structured container conforming to strict OS architecture formats:

Header & Magic Bytes Signals the target processor architecture (e.g. 64-bit x86 vs. ARM) and validates format integrity.
Text Segment (Code) Pure binary machine instructions ready to be executed by CPU execution units (Read-Only).
Data Segment Initialized global variables, numeric constants, and fixed string literals.
Import Table & Dependencies A list of external shared libraries (e.g., kernel32.dll or libc.so) required at runtime.

4. Does the Whole Program Copy to RAM? (The Lazy Loading Myth)

A common beginner misconception suggests: "When you launch a 50 GB game or a 2 GB photo editing tool, the OS copies all 50 GB from SSD into RAM before opening."

In reality, this never happens! Modern operating systems do not load entire binary images upfront. Instead, they rely on Memory Mapping (mmap) and Demand Paging.

The OS merely maps the file's address range and reads the primary header and entry page into physical RAM. The remaining code pages are fetched from disk on-demand only when CPU instruction execution actually reaches them (triggering a Page Fault). This elegant design is called Lazy Loading.

5. Process Creation & Virtual Address Space

The kernel initializes a new tracking structure called the Process Control Block (PCB), which manages the application's unique Process ID (PID), credentials, open file descriptors, and CPU execution state.

The Splendid Illusion of Virtual Memory

The kernel bestows upon each new process an expansive, private, and contiguous Virtual Address Space (spanning up to 128 Terabytes on modern 64-bit platforms).

Process A Virtual Space ──[MMU Page Table]──► Physical RAM (Frame #42)
Process B Virtual Space ──[MMU Page Table]──► Physical RAM (Frame #89)

A process can never address or inspect another process's virtual memory space. This strict physical boundary guarantees that one crashing program never corrupts neighboring tasks.

6. What Lives Inside Process Memory?

The virtual memory layout of every running process is partitioned into four primary functional regions:

Stack Segment (↓ Grows Downward)
Function call frames, local variables & return addresses
↕ Dynamic Free Address Space ↕
Heap Segment (↑ Grows Upward)
Dynamic memory allocations (malloc / new)
Data / BSS Segment (Global & static variables)
Text Segment (Compiled machine code — Read-Only)

7. Shared Libraries & The OS Loader

Production software relies heavily on system-provided shared libraries for networking, UI windowing, and math routines (.dll files on Windows, .so on Linux).

Duties of the OS Dynamic Loader / Linker:

  • Parse the executable's import table and map required dynamic libraries into memory.
  • Patch unresolved function addresses (Symbol Resolution & Relocation).
  • Execute library constructors and initialize shared subsystem states.

8. The Entry Point and the Mystery Before `main()`

Every programmer is taught that program execution starts at main(). In actual operating system reality, this is an oversimplification.

Entry Point vs. `main()`:

The true hardware address where the CPU first lands is the binary's Entry Point (typically labeled _start on Linux). Critical runtime bootstrapping occurs before main() ever runs:

1. _start → Receives CLI arguments (argc, argv) from the kernel stack
2. C Runtime (CRT) Init → Initializes global static object constructors
3. Environment Setup → Prepares standard I/O streams (stdin, stdout, stderr)
4. Call main() → Finally jumps into your application's source logic!

9. The CPU Scheduler & Multicore Execution

Even when a process is fully staged in memory, it cannot simply commandeer the CPU at will. The kernel's Scheduler decides precisely which thread executes on which physical core during each millisecond quantum.

// Multi-core Scheduling Matrix
CPU Core 0 Chrome (Thread 1)
CPU Core 1 VS Code (Thread 1)
CPU Core 2 Spotify Audio Engine
CPU Core 3 OS Background Daemons

Process vs. Thread:

A Process is a protected container owning memory and system resource handles; a Thread is the active path of instruction execution within that container. A single process can spawn multiple threads sharing the same memory to execute work in parallel.

10. The CPU Execution Cycle & Regular Function Calls

When the scheduler loads a thread's state into a CPU core, the processor engages its timeless silicon rhythm: Fetch → Decode → Execute.

What happens during a regular function call?

When executing calculate();, the CPU pushes the return address onto the local thread stack and jumps to the target instruction address. Upon returning, it pops the stack. This is a purely user-space operation involving no operating system system calls or privilege shifts.

11. Runtime System Interactions & Painting Windows on Screen

Whenever the program reads files or streams web traffic, it dispatches system calls to the kernel.

When it is finally time to display a graphical window:

1. Application Event Loop → Calls Win32 / Cocoa / Wayland / X11 APIs
2. Window Compositor → Allocates window dimensions and desktop coordinates
3. Graphics Driver → Builds DirectX / Vulkan / Metal command buffers
4. GPU Rendering → Renders pixels into the display framebuffer at 60/120 Hz!

12. The Process Lifecycle: 3 Core States

A process never hogs the CPU continuously. It transitions dynamically across three fundamental lifecycle states:

Running

Instructions are actively being processed by a CPU core right now.

Ready

Prepared to execute, waiting in the scheduler's queue for a CPU core.

Blocked / Waiting

Waiting for disk I/O, user keystrokes, or network packets (consumes 0% CPU).

13. What Happens When You Close an App? (Resource Reclamation)

When you click the red 'X' button or choose Exit from a menu:

1.The process invokes the exit() system call requesting termination.
2.The kernel closes all associated open file descriptors and network sockets.
3.Virtual memory page tables are unmapped, returning physical RAM frames to the OS free list.
4.The PCB entry is retired from the process table, completely dissolving the process.

Crucially, the original App.exe binary file on your SSD remains untouched, ready to be spawned into brand new processes whenever needed!

14. The Complete Pipeline at a Glance

USER (Double Click on App Icon)
↓ Input Interrupt ↓
OS Shell & File System (Find Executable)
↓ Read Metadata ↓
OS Kernel (Create Process & Virtual Memory Space)
↓ Demand Paging ↓
Dynamic Loader (Bind Shared Libraries)
↓ Jump to Entry Point ↓
Runtime Initialization → main() Function
↓ Scheduling Quantum ↓
CPU Core (Fetch • Decode • Execute Loop)
↓ Graphics API & GPU Compositor ↓
MONITOR DISPLAY (App Window is LIVE!)

15. Why Do Applications Launch in Milliseconds?

Considering how many dozens of intricate operations take place, why do applications open in the blink of an eye on modern devices? Through remarkable architectural optimizations:

NVMe SSD Bandwidth Modern flash drives stream data at blazing speeds of 4,000–7,000 MB/s.
OS Page Caching Shared system libraries already reside warm in RAM, avoiding redundant disk I/O.
Demand Paging (Lazy Loading) Only the tiny initial code slice is loaded, getting the UI onscreen immediately.
Multi-core Initialization Libraries and assets load concurrently across multiple CPU threads.

🧠 Key Takeaways

  1. A Program is code stored on disk; a Process is that code executing in RAM: A single program can spawn multiple running processes.
  2. Programs are not dumped into RAM all at once: Virtual memory demand paging loads pages on the fly as execution demands them.
  3. Every process receives an isolated Virtual Address Space: Divided into Text (code), Data, Heap (dynamic memory), and Stack (local frames).
  4. Runtime startup occurs before `main()`: The OS jumps to the entry point (_start) to setup args, env, and runtime before calling main().
  5. The Scheduler commands the CPU: Distributing threads across cores in precise millisecond quantum slices.
  6. Processes cycle across three states: Running on a core, Ready in queue, or Blocked waiting for I/O.
  7. Exiting reclaims all memory and handles: Cleaning the slate while preserving the stored binary for future runs.
🚀 Next Lesson

Lesson 07 — How Memory Runs Programs: RAM, Stack, Heap & Virtual Memory

Where exactly does a living process store its variables and data? What makes the Stack blazingly fast but bounded, and how does the Heap cause memory leaks?

"Mastering memory mechanics is the defining bridge transforming a novice coder into a true systems architect."
Start Lesson 07