Before generating any executable file, program has to travel many stages of compilation. each stage of compilation has its own significance. If it fails at any step it may not lead to further. So it is programmer responsibility to make compiler happy.
Stages are -
1) Pre-processing
2) Compilation
3) Assembler
4) Linker
Pre-processing
This is the very first stage of compilation. at this all stage all includes files, macro defines get expended and if any issue with include file it will display here itself. it is better illustrated with following example hello.c
Now compile the above code, to see just Pre-processing stage, compile with following options
$ gcc -E Hello_world.c
-E options expand all macros, but it will display all expansion on terminal itself. A better way to keep all into a single file is redirect to a file with extension .i.
or
If -save-temps option is used in compilation, then all stage file generate in one shot. that we dont want now..
Compilation
All code here after will convert into machine language(low level language) hello.s. To illustrate this -S option can be used which produce hello.s file
And hello.s file will look like
Assembler
Here is the stage where all syntax used in c program is checked. If any syntax error or function prototype mismatch or unused variable, undefined variable, redefine variables preset in the code, will be thrown as error or warning by the compiler .In this stage all code converts from machine code to object code and one object file is generated with extension of hello.o. That can be seen separately by using following command.
-Wall gcc option will throw all kind of warning that was found during compilation. If everything goes smooth the an object file will be generated which is nothing but complied file only that contains all symbols (all global variables, functions etc.. ) used in code.
Linker
This is last and final stage of compilation where all the linker combine all symbol objects together and form an executable file. if any Static library used in code that also linked at this stage only by using -l<lib name> option.
an executable file 'run' is generated. Now run the 'run'.
Note. you can notice that #define MAX 100 replace second argument of printf(), but not in first one because first argument is treated as control string or like string. that is why out put looks like
Stages are -
1) Pre-processing
2) Compilation
3) Assembler
4) Linker
Pre-processing
This is the very first stage of compilation. at this all stage all includes files, macro defines get expended and if any issue with include file it will display here itself. it is better illustrated with following example hello.c
#include <stdio.h>
#define MAX 100
int main()
{
printf("MAX : %d\n",MAX); return 0;
}
Now compile the above code, to see just Pre-processing stage, compile with following options
$ gcc -E Hello_world.c
-E options expand all macros, but it will display all expansion on terminal itself. A better way to keep all into a single file is redirect to a file with extension .i.
$ gcc -E Hello_world.c > hello.i
$ ls
hello.c hello.i
$ gcc -save-temps hello.c
$ ls
a.out hello.c hello.i hello.o hello.s
If -save-temps option is used in compilation, then all stage file generate in one shot. that we dont want now..
Compilation
All code here after will convert into machine language(low level language) hello.s. To illustrate this -S option can be used which produce hello.s file
$ gcc -S hello.i
$ ls
hello.c hello.s
And hello.s file will look like
$ cat hello.s
.file "hello.c"
.section .rodata
.LC0:
.string "MAX : %d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $100, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
Assembler
Here is the stage where all syntax used in c program is checked. If any syntax error or function prototype mismatch or unused variable, undefined variable, redefine variables preset in the code, will be thrown as error or warning by the compiler .In this stage all code converts from machine code to object code and one object file is generated with extension of hello.o. That can be seen separately by using following command.
$ gcc -Wall -c hello.s
$ ls
hello.c hello.o hello.s
-Wall gcc option will throw all kind of warning that was found during compilation. If everything goes smooth the an object file will be generated which is nothing but complied file only that contains all symbols (all global variables, functions etc.. ) used in code.
Linker
This is last and final stage of compilation where all the linker combine all symbol objects together and form an executable file. if any Static library used in code that also linked at this stage only by using -l<lib name> option.
$ gcc -o run hello.s
or
$ gcc -o run hello.c
or
$ gcc -o run hello.o
or
$ gcc -o run hello.i
$ ls
hello.c hello.i hello.o hello.s run
an executable file 'run' is generated. Now run the 'run'.
$ ./run
MAX : 100
Note. you can notice that #define MAX 100 replace second argument of printf(), but not in first one because first argument is treated as control string or like string. that is why out put looks like
MAX : 100
Nice discussion
ReplyDeleteThis comment has been removed by the author.
ReplyDelete