C program compilation process
The C code compilation process involves several stages that transform human-readable source code into machine-executable binary code. Here's a detailed explanation of each stage in the compilation process:
1. Preprocessing
- Input: Source code files (
.c
files) with preprocessor directives (e.g.,#include
,#define
). - Output: Preprocessed source code.
- Description: The preprocessor handles directives by performing tasks such as file inclusion (
#include
), macro expansion (#define
), and conditional compilation (#ifdef
,#ifndef
). The result is a single source file with all headers included and macros expanded.
Example:
Source file (main.c
):
#include <stdio.h>
#define MAX 100
int main() {
printf("MAX is %d\n", MAX);
return 0;
}
Preprocessed file (main.i
):
// Content of stdio.h included here
int main() {
printf("MAX is %d\n", 100);
return 0;
}
2. Compilation
- Input: Preprocessed source code (
.i
files). - Output: Assembly code (
.s
files). - Description: The compiler translates the preprocessed source code into assembly language, which is a low-level, human-readable representation of the machine code specific to the target CPU architecture.
Example:
Preprocessed file (main.i
):
int main() {
printf("MAX is %d\n", 100);
return 0;
}
Assembly file (main.s
):
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 15
.globl _main
.p2align 4, 0x90
_main:
pushq %rbp
movq %rsp, %rbp
leaq L_.str(%rip), %rdi
movl $100, %esi
xorl %eax, %eax
callq _printf
xorl %eax, %eax
popq %rbp
retq
L_.str:
.asciz "MAX is %d\n"
3. Assembly
- Input: Assembly code (
.s
files). - Output: Object code (
.o
or.obj
files). - Description: The assembler converts assembly code into object code, which is a binary representation of the machine instructions. The object code is still not executable because it may have unresolved references to other object files or libraries.
Example:
Assembly file (main.s
):
.section __TEXT,__text,regular,pure_instructions
...
Object file (main.o
):
- Binary data representing machine instructions and data.
4. Linking
- Input: Object code files (
.o
or.obj
files), libraries. - Output: Executable file (
a.out
,main.exe
, etc.). - Description: The linker combines multiple object files and libraries into a single executable file. It resolves symbol references, such as function calls and global variables, and addresses any dependencies between the compiled modules.
Example:
Object files (main.o
, stdio.o
):
- Binary data representing machine instructions and data.
Linked executable (main
or main.exe
):
- A complete, standalone binary file ready to be executed by the operating system.
5. Loading and Execution
- Input: Executable file.
- Output: Running program.
- Description: When the executable file is run, the loader (part of the operating system) loads it into memory, sets up the runtime environment, and starts the execution of the program by jumping to the entry point (usually the
main
function).
Example:
Executable (main
):
$ ./main
MAX is 100
Published on: Jun 25, 2024, 07:54 AM