美文网首页
gcc编译过程简单介绍

gcc编译过程简单介绍

作者: besmallw | 来源:发表于2020-03-31 22:43 被阅读0次

写了好几年代码了,一直记不住gcc是如何编译。今天特地写篇笔记记录下来,以后忘记了还可以回来看笔记。

对于一个深爱着C语言的我来说,灵活使用gcc编译器非常重要,加深对C语言的理解也很重要。

生成可执行文件期间有4个步骤:

1、预编译
2、编译
3、汇编
4、链接

0、编写C文件test.c

C文件.png

1、预处理阶段

处理预处理指令(#include #define #ifdef 等 大多数带#的),并删除注释和多余的空白字符,生成一份新的代码。(这里生成的还不是汇编文件)

命令: gcc -E -o test.i test.c
-E 解释:
Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output.
Input files that don't require preprocessing are ignored.
(在预处理阶段之后停止;不要正确运行编译器。输出以预处理源代码的形式发送到标准输出。不需要预处理的输入文件将被忽略。)

-o 解释:
后面跟输出的文件名,如果不加 -o 选项的话,输出的文件默认是 a.out
gcc -E test.c操作的结果输出到 test.i

预处理会将#include <stdio.h>作一个简单的替换,打开test.i文件:

预编译文件.png
796行往上的就是#include <stdio.h>替换的结果

2、编译

对代码进程语法分析、词语分析、错误检查,生成汇编代码。还没生成二进制文件。(这一步还会对代码进行优化)
命令:gcc -S -o test.s test.i
-S 解释:
Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each non-assembler input file specified.
By default, the assembler file name for a source file is made by replacing the suffix .c, .i, etc., with .s.
Input files that don't require compilation are ignored.
(在适当的编译阶段之后停止;不要汇编。对于指定的每个非汇编程序输入文件,输出都是汇编程序代码文件的形式。默认情况下,源文件的汇编程序文件名是通过将后缀.c、.i等替换为.s来生成的。不需要编译的输入文件将被忽略。)

汇编代码.png

3、汇编

通过汇编文件,生成机器代码。还没链接。
目标文件由段组成,通常一个目标文件中至少有两个段:

  • 代码段:主要包含程序的指令。该段一般是可读和可执行的,一般不可写。
  • 数据段:主要存放程序中用到的各种全局变量和静态的数据。一般数据段是可读、可写、可执行的。

命令:gcc -c -o test.o test.s
-c 解释:
Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
By default, the object file name for a source file is made by replacing the suffix .c, .i, .s, etc., with .o.
Unrecognized input files, not requiring compilation or assembly, are ignored.
(编译或汇编源文件,但不链接。链接阶段根本没有完成。最终输出是每个源文件的对象文件形式。默认情况下,源文件的对象文件名是通过将后缀.c、.i、.s等替换为.o来生成的。不需要编译或汇编的无法识别的输入文件将被忽略。)
打开test.o文件,发现完全看不懂,这就对了。反正计算机能看懂。

4、链接

将多个 .o 文件合并为一个可执行文件。
命令:gcc -o test test.o
生成可执行文件 test
可以使用命令 objdump -d test 查看汇编(二进制指令转汇编)

二进制转汇编.png

根据开发人员指定的同库函数的链接方式的不同,链接处理分为两种:

  • 静态链接:
    函数代码将从其所在的静态链接库中被拷贝到最终的可执行程序中。
  • 动态链接:
    此时,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所做的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的信息,在可执行程序被执行时,动态链接库的全部内容将被影射到运行时相应进程的虚拟地址空间。动态链接程序将根据可执行程序中记录的信息找到对应的函数代码。
  • 备注:使用动态链接能使最终的可执行文件较小,并且当共享对象被多个进程使用时能节约一些内存,因为在内存中只需要保存一份此共享对象的代码。

5、运行

运行.png

部分内容转自:C语言编译过程


2020.3.31 22:43 广州

相关文章

  • gcc编译过程简单介绍

    写了好几年代码了,一直记不住gcc是如何编译。今天特地写篇笔记记录下来,以后忘记了还可以回来看笔记。 对于一个深爱...

  • Makefile基础

    介绍 Wikipedia上的 Makefile介绍。简单来说:  Makefile就是告诉gcc/g++如何编译项...

  • gcc 编译过程

    在执行上面语句时,-o实际上分多步来处理.c文件。下面我们讲一下gcc的编译过程。 预处理器处理 首先gcc使用预...

  • GCC编译过程

    第一步:进行预编译,使用 -E 参数 gcc-Etest.c-o test.i 查看 test.i 文件中的内容,...

  • 编译纯C文件

    ①最为简单的编译方法为 gcc -c hello.c //编译成.o文件。 gcc -o hello hello...

  • gcc如何编译.c 文件、gcc编译过程以及编译的主要参数

    gcc如何编译.c 文件、gcc编译过程以及编译的主要参数如何编译.c 文件假如在当前目录下存在两个文件hello...

  • Clang 与 GCC 的区别

    1. 介绍 1.1 GCC GCC:GNU(Gnu's Not Unix)编译器套装(GNU Compiler C...

  • 编译适用arm 架构的so

    在 jni 调用 那篇,我们介绍了使用 gcc 编译so 库,但是在Mac 系统下,直接使用默认的gcc 编译so...

  • gcc编译器编译过程

    第一步:预处理阶段 终端编译代码: gcc -E demo1.c -o demo1.i 对demo1.c作预处理生...

  • gcc相关

    gcc编译常用指令 gcc编译过程 gdb调试流程 第一步生成调试文件 第二步 根据指令调试

网友评论

      本文标题:gcc编译过程简单介绍

      本文链接:https://www.haomeiwen.com/subject/tzzguhtx.html