Ads

Compilation Stages of C program


STEPS FOR EXECUTION OF C PROGRAM

- After we create our source code we have to execute it.

- To obtain the executable file there are few steps where our source program will undergo conversions till executable file is generated.

- All the below conversion takes place internally we can directly get the executable file using single command gcc filename.c, but still if one want to know how the internal conversion takes place below are the stages.

- The stages  are
  • Pre-Processor stage
  • Compiler stage
  • Assembler stage
  • Linker stage

PRE-PROCESSOR STAGE:

- Source code is the program what we have written using an editor or an IDE. Totally source code is the C program what we have created. It has an extension of .c

- This source code is sent through pre-processor where our source code is expanded, comments are removed and Macros are replaced. 

- The respective command for this stage is

 cc -E file_name.c

- It prints the code on terminal which is obtained after pre-processing.

- To obtain the expanded code in a file the command in Linux is

cc -E file_name.c  -o file_name.i

- After above said command is executed a file file_name.i is generated in present working directory and whole code obtained after pre-processing stage is stored in this file. We can open that file and view the whole content.
(Here -o filename.i means asking pre-processor to save the content in a file filename.i. You can give any name instead.)

- At this stage following changes happen
  • Header file is expanded.
  • Comments are removed
  • Macros are replaced

- Let us consider an example program

Program:


/* This program prints hello world on standard output */
#include<stdio.h>
#define pf printf // This is a macro
int main()
{
 pf("\nHello world\n"); // This instruction prints hello world
 return 0;
}


- The content after pre-processing stage looks similar to
# 1 "stage_test.c"
# 1 "<command-line>
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "stage_test.c"
# 20 "stage_test.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 374 "/usr/include/features.h" 3 4
# 1 "/usr/include/i386-linux-gnu/sys/cdefs.h" 1 3 4
# 385 "/usr/include/i386-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
# 386 "/usr/include/i386-linux-gnu/sys/cdefs.h" 2 3 4
# 375 "/usr/include/features.h" 2 3 4
# 398 "/usr/include/features.h" 3 4
# 1 "/usr/include/i386-linux-gnu/gnu/stubs.h" 1 3 4
.
.
.
.
# 21 "stage_test.c" 2
int main()
{
printf("\nHello World\n");
return 0;
}

- By watching the above content we can say that macros are replaced, comments are removed and the line #include<stdio.h> is been replaced with large content so we can say that header file is exapanded.

COMPILER STAGE:

- At compiler stage on the basis of expanded code i.e. dot i (.i) file or on the basis of our source code dot c (.c) files, a file with .s as extension is generated which consists assembly code.

- This assembly code is generated on the basis of our code i.e depending upon what functions and what structure we have used in our C program. And the generation is handled by compiler.

- To obtain the assembly code the commands we can use are

cc –S file_name.c
or
cc –S file_name.i

- assembler accept files with .i extension or .c extension

- You can also use cc –S file_name.i -o file_name.s if we want to change the obtained file name to any other specific file name.

- For example cc -S file_name.i -o file_aft_asm.s Now instead of file_name.s generated code is saved in file_aft_asm.s

- If we open up the .s file we can see all the assembly instructions thus we can say that the whole code is converted to assembly code.

- The generated code looks like

.file        "stage_test.c"
.section                .rodata
.LC0:
.string   "\nHello World"
.text
.globl     main
.type     main, @function
main:
.LFB0:
.cfi_startproc
pushl     %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl      %esp, %ebp
.cfi_def_cfa_register 5
andl       $-16, %esp
subl        $16, %esp
movl      $.LC0, (%esp)
call          puts
movl      $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size       main, .-main
.ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section                .note.GNU-stack,"",@progbits

- By observing the code we can say that it is assembly language and hence the compiler generated assembly language for us.

ASSEMBLER STAGE:

- Assembler converts the assembly code to object code(machine code) so at assembler stage a file with .obj(windows) or .o(Linux) extension is generated.

- The commands are
cc –c file_name.c
or
cc –c file_name.i
or
cc -c file_name.s

- Or we can also use cc –c file_name.s –o file_name.o to get the obtained file with a different name. Similar to command in compiler stage.

- We cannot see the contents of object file. The content somewhat look like below
ELF###\00\00\00\00\00\00\00\00\00#\00#\00#\00\00\00\00\00\00\00\00\00\00\00##\00\00\00\00\00\004\00\00\00\00\00(\00
\00
\00U‰åƒäðƒ
.
.
.

LINKER STAGE:

- At linker stage other object files are linked for example the library files. Library files are pre-compiled files which can be directly linked at linker stage after linker stage an executable file is generated.

- Command
gcc file_name.c

- Executing above command generates a file with name a.out which is the executable format of last compiled c-program. Everytime a new file is compiled the a.out is replaced with new executable file thus to retain the executable content we can store it in any other file by renaming it by using the similar command as we used in assembler and compiler stages.

gcc file_name.c -o file_name

- To run the executable we have to place ./ preceding to file_name
./a.out
or
./file_name

- An executable file have extension .exe in windows and it is named a.out in Linux.

- To get all the files in one shot we can use command

gcc –save-temps file_name.c -o file_name



Below files are generated using the above command
A pre-processed file                      : file_name.i
File after compiler stage              :  file_name.s
An object file                                 :  file_name.o
An executable file                         :  file_name



No comments:

Post a Comment