CD Notes
Detailed walkthrough of the entire compilation pipeline from source code to program execution
Understanding the complete compilation process from source code to execution is fundamental to computer science. This comprehensive guide walks through each stage.
The Full Language Processing System
A complete language processing system consists of multiple interconnected components:
Stage 1: Source Code Preparation
Stage 2: Preprocessing
Command: gcc -E program.c -o program.i
Stage 3: Compilation
Command: gcc -S program.i -o program.s
The compiler performs:
- Lexical Analysis (Tokenization)
- Syntax Analysis (Parsing)
- Semantic Analysis (Type checking)
- Intermediate Code Generation
- Code Optimization
- Code Generation
| / | \ |
|---|---|
| / | \ |
Stage 4: Assembly
Command: gcc -c program.s -o program.o
The assembler converts assembly to machine code:
Stage 5: Linking
Command: gcc program.o -o program
The linker combines object file with libraries:
Inputs
program.o (our compiled code)
libc.so/libc.a (C standard library)
ld-linux.so (dynamic linker)
crt1.o, crti.o, crtn.o (runtime startup)
Linking Process
┌─────────────────────────────────────┐
│ 1. Collect all symbols │
│ main, printf, etc. │
├─────────────────────────────────────┤
│ 2. Resolve references │
│ printf → libc.so/printf │
├─────────────────────────────────────┤
│ 3. Assign memory layout │
│ .text @ 0x401000 │
│ .data @ 0x402000 │
├─────────────────────────────────────┤
│ 4. Process relocations │
│ Update call addresses │
├─────────────────────────────────────┤
│ 5. Output executable │
│ ELF executable file │
└─────────────────────────────────────┘
Output (program - executable)
┌────────────────────────┐
│ ELF Header │
├────────────────────────┤
│ Program Headers │
├────────────────────────┤
│ .text section │
│ (all code combined) │
├────────────────────────┤
│ .data section │
│ (all data combined) │
├────────────────────────┤
│ .dynamic section │
│ (dynamic link info) │
├────────────────────────┤
│ .dynsym section │
│ (exported symbols) │
└────────────────────────┘
Stage 6: Loading and Execution
Command: ./program
OS Actions
1. Read executable from disk
2. Allocate memory:
- .text section @ 0x401000
- .data section @ 0x402000
- .bss section @ 0x403000
- heap starts @ 0x404000
- stack starts @ 0x7fff0000
3. Resolve dynamic libraries:
- Load libc.so into memory
- Resolve printf address
4. Set up stack:
- Push environment variables
- Push command-line arguments
- Initialize argc, argv
5. Jump to entry point (_start)
Memory Layout During Execution
High Address ┌──────────────────┐
│ Stack │
│ (grows down) │
├──────────────────┤
│ Unallocated │
│ heap space │
├──────────────────┤
│ Heap │
│ (grows up) │
├──────────────────┤
│ .bss section │
├──────────────────┤
│ .data section │
├──────────────────┤
│ .text section │
├──────────────────┤
│ ELF header │
Low Address └──────────────────┘
Execution
program starts at entry point (_start)
→ calls main()
→ executes: int arr[100];
→ executes: printf("Hello");
→ returns 0
→ exits
Complete Command Summary
# Step-by-step compilation
gcc -E program.c -o program.i # Preprocessing
gcc -S program.i -o program.s # Compilation
gcc -c program.s -o program.o # Assembly
gcc program.o -o program # Linking
./program # Execution
# Or in one command
gcc -o program program.cCompilation Information
| Phase | Input | Output | Tool |
|---|---|---|---|
| Preprocessing | .c (with directives) | .i (expanded) | Preprocessor |
| Compilation | .i (code) | .s (assembly) | Compiler |
| Assembly | .s (assembly) | .o (machine code) | Assembler |
| Linking | .o + libs | executable | Linker |
| Loading | executable | memory | Loader |
| Execution | memory | output | CPU |
Interview Q&A
Q: Explain the complete compilation process from source to execution. A: Preprocessing expands macros and includes files, compilation translates to assembly code, assembly converts to machine code in object files, linking combines object files with libraries, loading reads the executable into memory, and finally the CPU executes the program.
Q: What happens in each stage of compilation? A: Preprocessing handles directives, compilation does lexical/syntax/semantic analysis and generates code, assembly produces machine code, linking resolves references, and loading prepares memory for execution.
Q: Why are multiple stages needed instead of compiling directly to machine code? A: Multiple stages allow modularity (separate compilation of files), enable optimization opportunities, allow intermediate representation portability, and make error detection and debugging easier.
Q: What's the difference between compile-time and runtime? A: Compile-time is when the compiler processes the source code. Runtime is when the loader loads the executable and the CPU executes it.
Q: What information is needed during linking? A: Linking needs symbol tables (to resolve references), relocation information (to adjust addresses), library locations (to find external symbols), and memory layout information.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Complete Compilation Process.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Compiler Design topic.
Search Terms
compiler-design, compiler design, compiler, design, language, processing, system, complete
Related Compiler Design Topics