An executable file becomes a running program only after the operating system creates or prepares a process, maps program contents into memory, sets initial execution state, and lets the CPU begin executing instructions.
Learning Question
If the executable file already contains machine code, why is it not the running program?
An executable file is a file on disk.
A running process is an active execution instance managed by the operating system.
Those are different things.
The first mental model is:
An executable file is a loadable representation of a program. A process is the program while it is running, with memory, registers, operating-system state, and an active instruction stream.
Executable File Versus Process
The executable file contains information needed to run the program.
The process is what exists when the program is actually running.
| Concept | What It Is |
|---|---|
| executable file | a file containing machine code, data, and loading metadata |
| process | a running instance with memory, registers, and OS-managed state |
The same executable file can be used to start multiple processes.
Each process has its own runtime state.
If two terminal windows run the same executable, they are not sharing one set of local variables or one stack.
They are separate running instances created from the same file representation.
What the Operating System Does
When a program is launched, the operating system prepares a process image from the executable.
At a high level, this includes:
- reading the executable file’s loading metadata
- creating or replacing the process memory image
- mapping code and data into the process address space
- preparing runtime memory such as the stack
- setting initial register state, including the initial instruction address
- transferring control so the program begins executing
The exact details depend on the operating system and executable format.
On Unix-like systems, this often involves an exec-style operation that replaces a process image with a new program.
For this collection, the important boundary is simpler:
The executable file must be loaded into a process context before its instructions can run.
Process Address Space
A process has an address space: the range of virtual addresses the process can use.
The process address space contains regions for different purposes.
Common regions include:
- executable code
- read-only data
- initialized global data
- uninitialized global data
- heap
- stack
- mapped shared libraries
The exact addresses vary by operating system, build options, runtime environment, and address-space randomization.
The important idea is:
The running program does not use the executable file directly as a flat blob. Its code and data are mapped into a process address space.
Mapping Code and Data
The executable file contains machine code and data arranged for loading.
When the program starts, the operating system maps relevant parts into memory.
For example:
- code may be mapped as executable and read-only
- string literals may be mapped as read-only data
- initialized globals may be mapped into writable data regions
- uninitialized globals may be given zero-filled storage
The file provides the template.
The process receives memory regions based on that template.
This is why changing a local variable while a program runs does not rewrite the executable file on disk.
Runtime memory belongs to the process.
The executable file is the source of the initial program image.
The Stack at Process Start
Earlier chapters used the stack for function calls and local storage.
The stack also has to exist when the program begins.
The operating system prepares an initial stack containing startup information such as:
- command-line arguments
- environment variables
- auxiliary runtime information on some systems
The exact layout is platform-specific.
The important point is that the process starts with a prepared runtime environment, not just a pointer to instruction bytes.
Once execution begins, ordinary function calls use the stack as described in earlier chapters.
The Heap During Execution
The heap is runtime memory used for dynamic allocation.
For example:
int *p = malloc(sizeof(int));The executable file does not contain a pre-created object for every future malloc allocation.
Heap memory is obtained and managed while the process runs.
The C allocator and operating system cooperate to provide usable dynamic memory.
This distinction matters:
Stack frames and heap allocations are runtime process state, not static source-code text and not simply fixed objects inside the executable file.
Initial Instruction and Entry Point
The CPU needs to know where to begin executing.
The executable file records entry-point information.
When the program is loaded, the operating system sets the process’s initial instruction pointer so execution begins at the program’s entry point.
That entry point is usually not the C function main directly.
There is startup code that prepares the C runtime environment and then calls main.
At the C level, programmers often say:
The program starts at
main.
That is a useful source-level simplification.
At the executable/process level, the more precise statement is:
The operating system starts execution at the executable’s entry point, and runtime startup code eventually calls
main.
Shared Libraries and Dynamic Loading
Many C programs use library functions such as:
printf("%d\n", value);The code for such functions may come from shared libraries rather than being fully copied into the executable file.
When dynamic linking is used, the runtime environment may map shared libraries into the process address space and resolve function references.
This is why a process memory map often contains more than just the executable file’s own code and data.
It may include:
- the main executable
- the dynamic loader
- C library mappings
- other shared libraries
- stack and heap regions
This chapter does not need the full dynamic-linking mechanism.
The important point is that the process is a runtime composition of mapped code, data, and operating-system-managed state.
Process State Includes Registers
A process is not only memory.
It also has CPU execution state while it is running.
Important examples include:
- the instruction pointer
- stack pointer
- general-purpose registers
- flags
When the operating system lets the process run, the CPU uses this state to continue execution.
When the operating system pauses and later resumes the process, it must preserve enough state for execution to continue correctly.
This connects back to the first chapter:
Running means instructions changing registers, memory, and the next instruction to execute.
The process is the operating-system container in which that execution happens.
One Executable, Multiple Processes
Suppose the same executable is launched twice.
There is one file:
./addBut there can be two processes:
process A running ./add
process B running ./addEach process has its own stack, heap, registers, and execution progress.
They may map the same executable code from the same file, but their writable runtime state is separate.
This is why it is inaccurate to say that the executable file itself is “the running program.”
The executable file can be the source for many running instances.
Each running instance is a process.
Source Line, Executable Bytes, Running Instruction
The full path now has three different views:
| View | Example Question |
|---|---|
| source code | What does this C statement mean? |
| executable file | What machine code and data were packaged for loading? |
| running process | What instruction is executing, and what are the current register and memory states? |
These views are related, but they are not the same.
Debuggers, disassemblers, and operating-system tools help connect them.
But the mental boundary should stay clear:
The executable is a file representation. The process is live execution state.
What This Chapter Does Not Explain Yet
This chapter explains the boundary between executable file and running process.
It does not yet fully explain:
- full ELF, PE, or Mach-O format details
- virtual memory implementation
- page tables
- demand paging
- address-space layout randomization in depth
- dynamic loader internals
- system calls in detail
- process scheduling
- kernel implementation
Those topics are real, but the first usable model is:
The operating system loads a program image into a process and starts execution with prepared memory and CPU state.
Core Mental Model
Keep these boundaries separate:
- An executable file is stored on disk.
- A process is a running instance created from a program image.
- The operating system maps executable code and data into the process address space.
- The process has runtime memory such as stack and heap.
- The process has CPU state such as registers and an instruction pointer.
- The executable entry point starts runtime execution; C
mainis reached through startup code. - The same executable file can produce multiple separate processes.
When thinking about a running C program, ask:
Am I reasoning about the file on disk, the memory image of one process, or the current instruction-level state while that process runs?
Final Summary
An executable file is the loadable representation of a program, but it is not the running program itself.
The operating system prepares a process from the executable, maps code and data into memory, sets up runtime state such as stack and registers, and starts execution at the program entry point.
The program is running only when those instructions execute inside a process.