What happens when you use gcc main.c
By David Orejuela

What happens when you use gcc main.c

No hay texto alternativo para esta imagen
No hay texto alternativo para esta imagen

gcc is a general collection of compilers which have all the necessary steps to convert an original source of code in c or c++ to something understandable for our computers.

In this post, we are going through every step of the process of creating an executable called main.c the which contains a .c code.



main.c source code:

/**
 * main - Hello world                                                       *                                  
 *                                                                                                                      
 * Return: Always 0 (Success)                                                             */                                                                                

#include <stdio.h>                                                                int main(void)                                                                     {                                                                                   return (0);                                                                        } 

The compiling process consist in the following steps:

No hay texto alternativo para esta imagen

PRE-PROCESSING

vagrant@vagrant-ubuntu-trusty-64:~/daorejuelablog/low_level$ gcc -E main.c 
#1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"



int main(void)
{
 return (0);
}

The first step consists on pre-processing the file, like in the case of filters, we are just leaving the information of relevance for the compiler, In this part, we produce a new code, that is less understandable for the human but still readable, the comments disappear and only the logic part of the program keeps having value, we can generate this code using the command: gcc -E main.c.

COMPILATION

vagrant@vagrant-ubuntu-trusty-64:~/daorejuelablog/low_level$ cat main.s
        .file   "main.c"
        .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    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4"

        .section        .note.GNU-stack,"",@progbits

The compilation process consists of transforming that preprocessed file to assembler code which is a detailed way to indicate the instructions that the machine must follow to follow the steps in our code, but still, our machine only understands bytes, so it is not in its final form.

ASSEMBLY

vagrant@vagrant-ubuntu-trusty-64:~/daorejuelablog/low_level$ gcc -C main.c 
vagrant@vagrant-ubuntu-trusty-64:~/daorejuelablog/low_level$ od -x a.out
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000020 0002 003e 0001 0000 0400 0040 0000 0000
0000040 0040 0000 0000 0000 1170 0000 0000 0000
0000060 0000 0000 0040 0038 0009 0040 001e 001b
0000100 0006 0000 0005 0000 0040 0000 0000 0000
0000120 0040 0040 0000 0000 0040 0040 0000 0000
0000140 01f8 0000 0000 0000 01f8 0000 0000 0000
0000160 0008 0000 0000 0000 0003 0000 0004 0000
0000200 0238 0000 0000 0000 0238 0040 0000 0000
0000220 0238 0040 0000 0000 001c 0000 0000 0000
0000240 001c 0000 0000 0000 0001 0000 0000 0000
0000260 0001 0000 0005 0000 0000 0000 0000 0000
0000300 0000 0040 0000 0000 0000 0040 0000 0000
0000320 06ac 0000 0000 0000 06ac 0000 0000 0000
0000340 0000 0020 0000 0000 0001 0000 0006 0000
0000360 0e10 0000 0000 0000 0e10 0060 0000 0000
0000400 0e10 0060 0000 0000 0228 0000 0000 0000
0000420 0230 0000 0000 0000 0000 0020 0000 0000
0000440 0002 0000 0006 0000 0e28 0000 0000 0000
0000460 0e28 0060 0000 0000 0e28 0060 0000 0000
0000500 01d0 0000 0000 0000 01d0 0000 0000 0000
0000520 0008 0000 0000 0000 0004 0000 0004 0000
0000540 0254 0000 0000 0000 0254 0040 0000 0000
0000560 0254 0040 0000 0000 0044 0000 0000 0000
0000600 0044 0000 0000 0000 0004 0000 0000 0000
0000620 e550 6474 0004 0000 0584 0000 0000 0000
0000640 0584 0040 0000 0000 0584 0040 0000 0000
0000660 0034 0000 0000 0000 0034 0000 0000 0000
0000700 0004 0000 0000 0000 e551 6474 0006 0000
0000720 0000 0000 0000 0000 0000 0000 0000 0000
*

Now our code in assembler is basic, it needs to be understood in bytes for the machine so the compiler converts it into a dump of bytes, which is understandable for the machine as commands.

LINKING

Now to create our code the compiler also has to include the libraries that we import, in this stage the code will importing and merge it with our normal code to produce working output main,out.

In basics, gcc is a command that allows the machine you are using to understand the source code that you want to execute, by compiling into the characteristics of your machine, making the c code portable and able to work, depending on the compiler used.

要查看或添加评论,请登录

David Orejuela的更多文章

社区洞察

其他会员也浏览了