How Computers Execute Code

At the lowest level, a CPU repeatedly does three things: fetch an instruction from memory, decode what it means, and execute it. Everything from Python scripts to video games reduces to this cycle.

Why It Matters

Understanding execution helps you reason about performance, debugging, and why some languages are fast and others are convenient. It’s the foundation for understanding Compilers vs Interpreters.

The Fetch-Decode-Execute Cycle

1. FETCH:   Read instruction at address pointed to by Program Counter (PC)
2. DECODE:  Figure out what operation + operands
3. EXECUTE: Perform the operation (add, compare, jump, load, store)
4. PC += 1  (or jump to new address)
5. Repeat

CPU Components

ComponentRole
ALUArithmetic & logic (add, subtract, AND, OR)
RegistersTiny, fast storage (8-64 of them)
Program CounterAddress of next instruction
Cache (L1/L2/L3)Fast memory between CPU and RAM
Control UnitOrchestrates fetch-decode-execute

From Source Code to Execution

Source code  →  [Compiler/Interpreter]  →  Machine code  →  CPU
   ↓                                          ↓
 "x = 1+2"                              MOV R1, 1
                                         ADD R1, 2
                                         STORE R1, [x_addr]

Code Example

# Python is interpreted — let's peek at the bytecode
import dis
 
def add(a, b):
    return a + b
 
dis.dis(add)
# Output:
#   LOAD_FAST    0 (a)
#   LOAD_FAST    1 (b)
#   BINARY_ADD
#   RETURN_VALUE
 
# The Python VM executes these bytecode instructions one by one.
# Each bytecode maps to C code in CPython, which eventually
# becomes real CPU instructions.

Levels of Abstraction

  High-level language    (Python, JavaScript)
        ↓
  Bytecode / IR          (Python bytecode, LLVM IR)
        ↓
  Assembly               (MOV, ADD, JMP — human-readable CPU instructions)
        ↓
  Machine code           (binary — what the CPU actually reads)
        ↓
  Microcode              (internal CPU operations)
        ↓
  Logic gates            (AND, OR, NOT — transistors)

Key Takeaway

Every line of code you write eventually becomes a sequence of simple operations: load a number, add two numbers, compare, jump. The layers of abstraction between your code and the CPU determine how fast it runs and how easy it is to write.