Table of Contents
KEY TAKEAWAYS
- C programs go through four stages: preprocessing, compilation, assembly, and linking before producing an executable
- The preprocessor handles directives like
#includeand#definebefore the compiler sees the code - The compiler converts C source code to assembly, then the assembler converts it to machine code (object files)
- The linker combines object files and resolves external references to produce the final executable
[c]#include<stdio.h>#define MAX_NUM 25int main(void){
printf("Hello worldn");
printf("The value of the MAX_NUM is = %dn",MAX_NUM);
return 0;
}[/c]Lets call this program comp_process.cIn this post, I’ll walk through each of the four stages of compiling the C program:Preprocessing:
This is the first phase in the compilation process. This phase include:- Removal of Comments – All the comments that we have in the file will be removed
- Expansion of Macros – All the macros will be expanded. In our program, the MAX_NUM macro will be replaced with the number 25
- Expansion of the included files – The contents of the ‘stdio.h’ file will be copied to output file
[c]cpp comp_process.c > comp_process.i[/c]In the image below, you can see the output of the command
[c]vi comp_process.i[/c]

Compilation:
Yes, that’s correct. Compilation is the second step in the process of compilation. In this stage, the pre-processed code is translated to assembly instructions specific to the target processor architecture. These form an intermediate human readable language. The output of this stage is a .S file. comp_process.i –> comp_process.s This step is accomplished by passing the -S option to gcc and the preprocessed file (.i) file.[c]gcc -S comp_process.i[/c]

Assembly
In this stage, the assembler is used to translate the assembly instructions to machine code, or object code. The output consists of actual instructions to be run by the target processor. In order to invoke the assembler, use the following command:[c]as comp_process.s -o comp_process.o[/c]
hexdump or od by running either of the following commands:- hexdump – It displays the contents of the file in hexadecimal format
[c]hexdump comp_process.o[/c]
- od – It displays the contents in octal format.
[c]od comp_process.c[/c]
Linking
The last step in the compilation process is the linking. The object code generated in the assembly stage contains the machine instructions that the processor understands. However, some pieces of the program are out of order or missing. In order to produce an executable program, the existing pieces have to be rearranged and the missing ones filled in. This process is called linking. Moreover, this stage links all the function calls with their definitions. Linker knows where all these functions are implemented. In the case of the our program, the linker will add the object code for the printf function. The result of this stage is the final executable program. When run without options,gcc will name this file a.out. To name the file something else, pass the -o option to gcc:Invoking gcc without the -o option
[c]gcc comp_process.c[/c]
Now, to execute the file run the following command[c]./a.out[/c]Invoking gcc with the -o option
[c]gcc -o compro comp_process.c[/c]
[c]./compro[/c]You can also see the output generated by the file
Save all the intermediate files
Invoking the gcc command on the c file generates the output file. In case you are in need the intermediate files, you can pass the command -save-temps to the gcc while invoking it. This will save the intermediate files on the hard disk.

Vivek Bhageria — Lead Firmware R&D Engineer, 12+ years. Ex-Bosch (automotive powertrain), MusicTribe (real-time audio), medical devices. M.Tech BITS Pilani. I write at NerdyElectronics — practical, register-level embedded systems for engineers who want to understand what’s actually happening under the hood.







