The journey of a C program through the gcc compiler!

Example of object code aka machine level code.

This journey begins with our C program fresh out of our text editor, for this example I created a program named 4-puts.c using the function puts() to print the sentence “Programming is like building a multilingual puzzle to standard output followed by a new line (\n).

Since is a special character I used \” to use it as a regular character inside my program.

There are four important components(modules) in the compilation process, I will explain a bit of what happens in each of the steps. In order to understand the process a bit better, I used the flag -save-temps to save the temporary files used in the gcc compiling process in my current directory alongside with my executable 4-puts file.

Pre-processing

From our previous step we obtained the 4-puts.i which is the output of our preprocessing component. During this step and inside our .i files we will find the tasks performed by the preprocessor which removes the comments from our file then it expands the files into source code in order to see the declaration of our puts() function, and a third important change is that all the macros are expanded. At the end of the file we will still find the lines of code written by us.

Last lines of my 4-puts.i file.

Compiling

When the pre-processing component is completed the compiler takes the 4-puts.i as input and generates a .s file containing assembly level instructions (hence the name) as output inside our 4-puts.s file. These are instructions defined by that our assembler can understand to turn it later into machine level language.

Content of my 4-puts.s file.

Assembly

This next component takes as input our 4-puts.s file to assemble those instructions into machine level code or object code our object file .o. In this component only the existing code is converted into machine language but it is not human readable, EFL on our first line of code stands for executable and linkable format and it is the format for machine level object files produced by gcc. The functions calls like our puts() are not yet resolved.

First lines of my 4-puts.o file

Linking

It is the final component where all the linking of function calls with their definitions are done, therefore this is the step where the definition of our puts() function is added to finally generate our executable file.

In our example named 4-puts. So the last thing left to do is to run our C program by using the command ./4-puts like so:

It will print our sentence with the special character and an added space (\n). That is the end our journey through the 4 components inside a gcc compilation.

Programmer in the making, English teacher and Industrial Designer, Avid Gamer and amateur mountain biker.