Program Execution
Program execution is the sequence of events by which an operating system and processor turn a stored program, a passive file of instructions, into an active running process that performs work. Double-clicking an application or typing a command begins a chain that involves the operating system creating a process, loading code into memory, giving it an address space, and then letting the processor carry out the instructions one after another until the program finishes or is stopped.
Execution begins with process creation and loading. On Unix-like systems a new process is usually made by the fork system call, which duplicates the calling process, followed by exec, which replaces the copy's contents with a new program; Windows uses CreateProcess to do both in one step. The operating system's loader reads the executable file (the ELF format on Linux, PE on Windows), maps its code and data sections into virtual memory, loads any shared libraries, sets up the initial stack with command-line arguments and environment variables, and points the processor's program counter at the entry point. Virtual memory gives each process its own private address space, so one program's bad memory access cannot overwrite another's, and pages are brought in from disk only when first touched.
Once running, the processor repeats the fetch-decode-execute cycle billions of times a second, the loop at the center of the von Neumann design. The program counter holds the address of the next instruction; the processor fetches it from memory, decodes it into an operation, executes it, and updates the counter, which normally moves to the next instruction but jumps when a branch, function call or loop says otherwise. Modern cores overlap these steps in pipelines and guess branches ahead of time to stay busy. Caches hide the delay of reaching main memory, which is why access patterns affect speed so heavily. The mechanics of the processor itself are the business of its own glossary entry; what matters here is that every high-level construct eventually becomes this loop over simple instructions.
A running process organizes its memory mainly into a stack and a heap, which behave very differently. The stack stores function call frames: arguments, return addresses and local variables are pushed when a function is called and popped when it returns, making allocation extremely fast but limited in size, so runaway recursion causes a stack overflow. The heap holds data whose lifetime is not tied to one call, allocated on request through calls such as malloc or by the new operator. It is flexible but must be freed, manually in C, by ownership rules in Rust or by a garbage collector in Java and Python; forgetting leaks memory, and freeing wrongly causes crashes and security holes. Beside them sit the code, constants and static data segments, and the operating system also schedules the process on the processor with preemptive time slices, so many programs appear to run at once.
Not every program executes as native machine code, and just-in-time compilation sits between the extremes. An interpreter runs bytecode through a virtual machine, which is portable but slower. A JIT compiler, used in the Java HotSpot virtual machine and the V8 engine of Chrome and Node.js, watches which code is hot, then compiles it to machine code during execution and can optimize using what it observes, at the cost of warm-up time and extra memory. Ahead-of-time compilation, as with C or Rust, pays that cost before the program ships. A frequent misunderstanding is that a program is the same thing as a process: one program file can be running as many independent processes, each with its own memory, and a single process can contain several threads that share it. Machine learning training follows the same model, where a Python process launches work onto GPUs as kernels, while the host process still drives it through ordinary instructions.
Read program execution as a stored file being brought to life: the operating system creates a process and loads the code into private memory, the processor then repeats fetch, decode and execute over it while stack and heap hold its working data, and techniques such as JIT compilation decide how much translation happens just before the instructions run.