gcc 编译过程
从 hello.c 到 hello(或 a.out)文件, 必须历经 hello.i、 hello.s、 hello.o,最后才得到 hello(或
a.out)文件,分别对应着预处理、编译、汇编和链接 4 个步骤,整个过程如图 10.5 所示。

这 4 步大致的工作内容如下:
(1) 预处理, C 编译器对各种预处理命令进行处理,包括头文件包含、宏定义的扩
展、条件编译的选择等;
(2) 编译,将预处理得到的源代码文件,进行“翻译转换”,产生出机器语言的目标
程序,得到机器语言的汇编文件;
(3) 汇编,将汇编代码翻译成了机器码,但是还不可以运行;
(4) 链接,处理可重定位文件,把各种符号引用和符号定义转换成为可执行文件中
的合适信息,通常是虚拟地址。

下面根据 hello.c 这个示例,跟踪一下其中的细节。
1)预处理
在 gcc 命令加上-E 参数,可以得到预处理文件。输入下列命令:
vmuser@Linux-host:hello$ gcc -E hello.c –o hello.i
将会产生 hello.i 文件,这就是 hello.c 经过预处理后的文件。实际操作结果见图 10.6。

图 10.6 预编译得到 hello.i 文件
一个原本连同空行才 8 行的代码,经过预处理,得到了一个 800 多行的预处理文件,文
件开的内容如图 10.7 所示。

图 10.7 hello.i 文件开头
hello.i 文件末尾处的内容如图 10.8 所示。

图 10.8 hello.i 文件末尾
其余部分内容请用 Vi 打开后进行查看。可以看到, hello.c 经过预处理后得到的 hello.i
文件,除了原本的几行代码之外,还包含了很多额外的变量、函数等等,这些都是预处理器
处理的结果。
2)编译
在 gcc 编译参数加上-S,可以将 hello.i 编译成 hello.s 文件。命令如下:
vmuser@Linux-host:hello$ gcc -S hello.i

实际操作和结果如图 10.9 所示。

图 10.9 编译得到 hello.s 文件
hello.s 是一个汇编文件,可用 Vi 编辑器打开查看,如图 10.10 所示。

图 10.10 hello.s 文件内容
可以看到,该文件内容都是汇编语句。这里不对汇编进行解释。
3)汇编
得到了汇编文件后,通过 gcc 就可以得到机器码了。在终端输入下列命令,可以得到
hello.o 文件。
vmuser@Linux-host:hello$ gcc -c hello.s
实际操作和结果如图 10.11 所示。

图 10.11 汇编得到 hello.o 文件
4)链接
尽管已经得到了机器码,但这个文件却还是不可以运行的,必须要经过链接才能运行。
在终端输入下列命令,将会得到可执行文件 a.out。
vmuser@Linux-host:hello$ gcc hello.o
操作和结果如图 10.12 所示。

图 10.12 链接得到 a.out 文件
a.out 是 gcc 默认输出文件名称,可以通过-o 参数指定新的文件名。例如加上“-o hello”
参数,将会生成 hello 文件,这个文件和 a.out 实际上是一样的,用 md5sum 命令计算文件校
验值,两者完全一样,如图 10.13 所示。

图 10.13 a.out 和 hello 文件
链接可分为动态链接和静态链接:
 动态链接使用动态链接库进行链接,生成的程序在执行的时候需要加载所需的动态
库才能运行。动态链接生成的程序小巧,但是必须依赖动态库,否则无法执行。
 Linux 下的动态链接库实际是共享目标文件(shared object),一般是.so 文件,
作用类似于 Windows 下的.dll 文件。
 静态链接使用静态库进行链接,生成的程序包含程序运行所需要的全部库,可以直
接运行,不过体积较大。
 Linux 下静态库是汇编产生的.o 文件的集合,一般以.a 文件形式出现。
gcc 默认是动态链接,加上-static 参数则采用静态链接。再来看 hello.c 示例,在链接的
时候加上-static 参数:
vmuser@Linux-host:hello$ gcc hello.o -static -o hello_static
操作命令和结果如图 10.14 所示,可以看到,动态链接生成的文件大小是 7155 字节,
而静态链接生成的文件却有 616096 字节,体积明显大了很多。

图 10.14 静态链接和动态链接结果对比

gcc 编译过程的更多相关文章

  1. Linux学习---GCC编译过程

    (一)GCC编译过程 预处理 cpp -o a.i a.c     //生成预处理文件 等同于[gcc -E] //预处理为将宏定义(#define)等进行替换. 编译 /user/lib/gcc/i ...

  2. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

  3. 1.GCC编译过程

    一. GCC编译过程 gcc -E hello.c -o hello.i // 预处理.将代码中包含的头文件和宏进行替换 gcc -S hello.i -o hello.s // 汇编.将当前文本转换 ...

  4. unix gcc编译过程

    gcc编译过程 现代编译器常见的编译过程: 源文件-->预处理-->编译/优化-->汇编-->链接-->可执行文件 对于gcc而言: 第一步 预处理       命令: ...

  5. GCC编译过程

    以下是C程序一般的编译过程: gcc的编译流程分为四个步骤,分别为:· 预处理(Pre-Processing) 对C语言进行预处理,生成*.i文件.· 编译(Compiling) 将上一步生成的*.i ...

  6. Linux系统GCC常用命令和GCC编译过程描述

    前言: GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理 C语言.GCC 很快地扩展,变得可处理 C++.后来又 扩展能够支持更多编程语言,如Fortran. ...

  7. gcc编译过程简述

    在linux系统上,从源文件到目标文件的转化是由编译器完成的.以hello.c程序的编译为例,如下: dfcao@linux: gcc -o hello hello.c 在这里,gcc编译器读取源文件 ...

  8. system 系统调用、gcc编译过程

    system 库函数的功能是执行操作系统的命令或者运行指定的程序 #include <stdio.h> #include <stdlib.h>//引入库 int main() ...

  9. 和菜鸟一起学c之gcc编译过程及其常用编译选项【转】

    转自:http://blog.csdn.net/eastmoon502136/article/details/8162626 版权声明:本文为博主东月之神原创文章,未经博主允许不得转载. 上篇文章,知 ...

随机推荐

  1. Docker安装Redis4.0

    docker pull redis:4.0 拉取Redis4.0镜像 docker images 查看本地的镜像 mkdir -p /root/redis4.0/data 在宿主机创建数据文件目录 w ...

  2. 监控进程cpu meminfo

    https://github.com/cdrandin/cpsc_351 https://github.com/cdrandin?after=Y3Vyc29yOnYyOpK5MjAxNC0wNy0xM ...

  3. node 单线程异步非阻塞

    链接:http://www.runoob.com/nodejs/nodejs-callback.html 首先什么是单线程异步非阻塞? 单线程的意思整个程序从头到尾但是运用一个线程,程序是从上往下执行 ...

  4. JMeter基础【第三篇】JMeter5.1元件作用域及执行顺序

    执行顺序,大家可以实践验证,加深印象. 最后,给大家说一个万能且保险的方法:放到对应的取样器下面即可.

  5. 用!htrace调试句柄泄漏的一般步骤

    Windbg调试器的!htrace扩展对于调试泄漏处理非常方便.该过程基本上可归结为以下简单步骤: 启用跟踪 拍张快照 情景分析 显示差异 在第四步!htrace将在最后一个快照之后显示所有额外打开的 ...

  6. Flask常用实列化参数

    Flask中实列化配置: app = Flask( __name__, template_folder=’temp’ , ...... ) >template_folder = "te ...

  7. 第02组 Alpha冲刺(2/6)

    队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 任务分配.进度监督 提交记录(全组共用) 接下来的计划 沟通前后端成员,监督.提醒他们尽快完成各自的进度 还剩下哪些任务 ...

  8. Android Studio 之 Navigation【1.页面之间的切换】

    1.创建 2个 Fragment ,下面两个include 不要勾 2.创建好 Fragment 后,打开layout中的 fragment.xml 文件,将里面默认的 textView 控件删除掉 ...

  9. CentOS环境设置Hbase自启动

    1.在/etc/init.d/目录创建hbase文件 #!/bin/bash # chkconfig: #export JAVA_HOME=/usr/local/jdk1.8.0_191 HBASE_ ...

  10. Java通过poi读取excel中文件

    maven依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</a ...