Source code is a description of a computation. Before a native program can run, tools and the operating system turn that description into a process with mapped code, data, stack, and access to machine resources. The exact pipeline depends on the language, toolchain, and operating system, but the boundaries are worth learning.
Translation and linking
A compiler commonly parses source text, checks language rules, transforms the program into an intermediate representation, optimizes it, and emits object code. An assembler encodes machine instructions and relocation information. The linker combines object files and libraries, resolves symbol references, and produces an executable or shared object. Some languages instead package bytecode or source for a virtual machine to execute later.
Static linking copies needed library code into the final executable. Dynamic linking leaves references that a loader resolves against shared libraries at startup or on demand. Neither model is universally better: static artifacts can simplify deployment while increasing size; shared libraries can reduce duplication and enable independent updates while adding runtime dependencies and compatibility constraints.
Loading creates an address space
When a program starts, the operating system creates a process context and maps executable and library segments into a virtual address space. The process receives an initial stack containing arguments and environment data. Runtime startup code initializes language-specific state before calling the program's entry point. Pages may be mapped lazily, so not all code or data must be read from storage immediately.
Virtual addresses are translated through page tables, often with help from a translation lookaside buffer. This isolates processes and lets each program use a convenient address layout, while the hardware and kernel manage physical memory beneath it.
Execution crosses interfaces
The processor fetches instructions, updates registers and memory, and follows branches. When the program needs a service such as file or network I/O, it uses a system interface. A system call crosses into the kernel, which validates the request and performs or schedules privileged work. A source-level function call, a library call, and a system call are therefore different boundaries even when a programmer writes them with similar syntax.
To study the full path, record which stage owns each responsibility: compiler, linker, loader, runtime, processor, or kernel. Computer Systems: A Programmer's Perspective develops this systems-level view.