A C program runs when the operating system creates a process from an executable form of the program and the CPU executes machine instructions that change registers and memory state.

Learning Question

When I write a C program and run it, what is actually running?

It is easy to say, “the C code runs.” That phrase is useful in everyday programming, but it is not what literally happens inside the machine.

The CPU does not execute C source code. The CPU executes machine instructions.

C source code is a human-readable representation of a program. Before it can run, it must be translated into lower-level forms, eventually becoming machine code inside an executable file. When the program starts, the operating system creates a process from that executable, prepares the process memory and initial execution state, and the CPU begins executing the program’s machine instructions.

The first mental model is:

Running a C program means executing machine instructions that change CPU state and memory state.

The Important Separation

Several different things are easy to mix together:

LevelWhat It IsWhat It Is For
C source codeText written by the programmerDescribing program behavior in a human-readable language
AssemblyHuman-readable form of low-level instructionsShowing how C operations map closer to the machine
Machine codeBinary instructions the CPU can executeThe actual instruction form executed by the CPU
Executable fileA file containing machine code and metadataA loadable representation of the program
ProcessA running instance of a programThe program while it is executing with its own memory and state

The C source file is not the running program itself. It is the starting representation.

The executable file is also not the running program by itself. It is a file that can be loaded.

The process is the running instance created from the executable.

The instruction stream is the sequence of machine instructions the CPU executes.

Path From Source to Execution

These concepts are not only different. They also appear at different points in the path from source code to execution:

C source code -> compiler -> machine code / object file -> linker -> executable file -> operating system creates process -> CPU executes instructions

This flow is simplified. Later chapters will separate compilation, linking, loading, and process creation more carefully.

For now, the important point is that C source code is transformed before execution, and the CPU executes instructions inside a running process.

What the CPU Actually Does

At a simplified level, the CPU repeatedly does this:

  1. Fetch the next instruction.
  2. Decode what the instruction means.
  3. Execute the instruction.
  4. Update CPU state and possibly memory state.
  5. Move to the next instruction.

This does not mean every real CPU works in such a simple step-by-step way internally. Modern CPUs use pipelining, caching, branch prediction, out-of-order execution, and other techniques.

For understanding how C runs, the simplified architectural model is the right starting point:

A program runs as instructions that read and write registers, access memory, perform calculations, and control which instruction comes next.

What Counts as CPU State?

CPU state means the information inside the CPU that affects execution.

The most important examples are:

  • registers
  • the instruction pointer
  • condition flags

A register is a small storage location inside the CPU. Registers hold temporary values that instructions operate on.

The instruction pointer holds the address of the next instruction to execute.

Condition flags record selected results of previous operations, such as whether a computed value was zero or whether a comparison had a particular result.

For now, the key point is not to memorize every register or flag. The key point is that execution is state change.

An instruction may change a register.

Another instruction may read a value from memory.

Another instruction may write a value back to memory.

Another instruction may change which instruction runs next.

That is program execution at the machine level.

What Counts as Memory State?

Memory state means the contents of memory visible to the running process.

A C program uses process memory for many things:

  • instructions
  • global variables
  • local variables
  • function call information
  • heap-allocated data
  • string literals
  • arrays and structs

Later chapters will separate these more carefully.

For this chapter, the important point is simpler:

A C variable, when it exists at runtime, is represented by values held in memory, held in registers, or moved between the two.

When a C program appears to assign a value to a variable, the lower-level reality is that instructions change storage locations.

That storage location may be a CPU register.

It may be a location in memory.

The value may also move between registers and memory during execution.

Example: A Simple C Statement

Consider this C statement:

result = left + right;

At the C level, this looks like one assignment statement.

At the machine level, the CPU cannot execute that C expression directly. The expression must become lower-level operations.

Conceptually, the machine-level work looks like this:

  1. Get the value of left.
  2. Get the value of right.
  3. Add the two values.
  4. Store the result somewhere associated with result.

This chapter does not need the exact assembly yet. The important idea is the mapping:

C ConceptLower-Level Meaning
leftA value stored in memory or a register
rightA value stored in memory or a register
+A CPU operation that adds values
result = ...A write to a storage location

A C expression is not directly executed as a C expression. It becomes a sequence of lower-level operations.

”A Line of C Runs” Is a Source-Level Shortcut

Programmers often say things like:

This line runs first. Then this line runs. Then the function returns.

This is acceptable when reasoning at the C language level.

But it hides the real execution model.

A line of C source code may become several machine instructions.

Several lines of C source code may be optimized into fewer instructions.

Some C variables may not exist as fixed memory slots for the whole function.

Some operations may happen in registers without being written to memory immediately.

Therefore, the phrase “this C line runs” should be understood as a source-level shortcut.

The more accurate statement is:

The compiled machine instructions corresponding to this part of the C program are executed.

This distinction matters because many low-level confusions come from mixing source-level concepts with machine-level mechanisms.

What This Chapter Does Not Explain Yet

This chapter only defines the basic meaning of execution.

It does not yet explain full assembly syntax.

It does not yet explain how the compiler produces object files.

It does not yet explain how linking works.

It does not yet explain stack frames, pointers, arrays, structs, or process memory layout.

Those topics need the first model to be clear first.

Before asking where variables live, what stack frames are, or why an assembly instruction uses an offset such as -20(%rbp), the base model must be:

The CPU executes instructions, and those instructions change registers and memory.

Core Mental Model

Keep these boundaries separate:

  • C source code describes program behavior for humans and for translation tools.
  • An executable file is a loadable representation of the program.
  • A process is the running instance created from the executable.
  • The CPU does not execute the C source file. It executes an instruction stream.
  • The instruction stream changes registers, memory contents, and the next instruction to execute.

Final Summary

A C program runs when its translated machine instructions are executed by the CPU inside a process.

Execution means those instructions change CPU registers, process memory, and the next instruction to be executed.