Basic steps in program execution

Before we get into all the components that executes a program, we'll briefly look at the sequence of events that occur when a program executes.

We'll use a program written in C.

#include <stdio.h>

int main() {
    printf("in da butt\n");
    return 0;
}

Program Launch

So we write this program, save it as whatwhat.exe and double click it. The OS kernel does 3 things: 1. creates a new process for our program 2. allocates a dedicated block of RAM for it, which will contain the program's code, data, and stack 3. reads the machine code instructions and data from the hard drive and copies it into this block of RAM

CPU Execution

The machine code now resides in RAM at the specific memory address. Windows gives the CPU the starting address of the program's main function.

The CPU's Instruction Pointer (EIP/RIP) is loaded with the memory address of the first instruction to be executed. Let's just assume the address is 0x401000.

Instruction (aka Fetch, Decode, Execute) Cycle Begins

This cycle is the beating heart of the CPU's operation.

Fetch:

1. The CPU uses the address of 0x401000 as a pointer to the memory location of the first instruction. 2. The first instruction of printf("in da butt\n"); is fetched from RAM and placed into the Instruction Register. 3. The machine is automatically incremented to point to the next instruction address of 0x401004 which is the return instruction.

Decode:

The CPU's Control Unit decodes the instruction in the Instruction Register, and recognizes it is a printf call that requests to output a string.

Execute:

1. The Control Unit neds to know what to print. The printf instruction contains a reference to the memory address of the string "in da butt\n". This address is a pointer to the data in RAM. 2. The Control Unit retrieves the string "in da butt\n" from its memory location. 3. The CU interfaces with the Windows kernel to send this string to the appropriate device driver for the output device, in this case the monitor. 4. In da butt shows up on our monitor. Cool people chuckle, boring people mumble childish. Whatever.

Program Termination

1. The CPU repeats the Fetch, Decode, Execute cycle but for the return 0 instruction. 2. The value 0 which indicates successful execution is placed in a General Purpose Register (likely RAX). 3. The Windows kernel receives this return value and terminates the process and frees the RAM for the next process.


Fun fact: how does the C code get turned into machine code?

This is a multi-step process involving a compiler and linker. 1. A preprocessor program takes directives like #include <stdio.h> and copies the contents of the stdio.h file into the source code file, resulting in a single, expanded C file. 2. A compiler takes the expanded C file and translates the C code into assembly code. 3. An assembler takes the translated assembly code file and converts it into an object file which contains the literal binary machine code. But the printf instructions are calls to an external function and the assembler doesn't know where it is. 4. A linker resolves the object file to all the external function calls. Basically it links the program's call to printf to the actual printf code in the library. 5. Lastly, the linker produces a final executable file that the OS can run.

Fun fact: what is the Windows kernel?

Part of the Windows OS, it's a computer program that has complete control over the system. It bridges the software applications and the physical hardware. It's key functions include management (e.g., resource, process and thread, memory), process orchestration, hardware abstraction (standardized interface for apps to interact with hardware, so that apps don't need to know the details of a particular GPU/hard drive. It just makes a request to the kernel, and the kernel handles the communications with the appropriate device driver.)

Fun fact: how does the Windows OS allocate the memory address?

The OS doesn't allocate a physical address, but more of a virtual address. This mapping between physical and virtual addresses is done with page tables. The CPU's Memory Management Unit does this translation on every memory access to ensure that each process operates securely only in its own space.

Last updated

Was this helpful?