文章

程序员的自我修养读书笔记

1.编译和链接

像VS,Delphi这种集成开发环境(IDE),他们一般把编译和链接的过程一步完成,将这种编译和链接合并到一起的过程叫做构建,构建的英文名是Build,所以你可以看到VS的编译就是这个词

2.中间的过程

比如一个hello world的小程序,编译过程也是很复杂的,可以分为4步:预处理,编译,汇编,链接

2.1预处理

对C语言来说,比如源文件是.c,那他就会把.c以及相关的头文件,全部被预编译器cpp预编译到一个文件里,这个文件是.i文件

源文件是.cpp,那就是到.ii文件

这两个文件其实就是预处理后的文件

预编译过程主要是解决了“#”开始的预编译指令,比如#include, #define这些

  • 把#include全部递归展开,把#define这些宏展开,并且删除#define
  • 处理所有的条件编译指令,比如”#if”, “#ifdef”, “#elif”, “#else”, “#endif”
  • 删除所有的注释 // 和 /**/
  • 添加行号和文件名标识,比如#2 “hello.c” 2,便于调试用,或者编译错误时显示行号
  • 保留所有的#pragma编译器指令,因为编译器需要使用他们

经过这些处理后的.i文件不包含宏定义,因为已经被展开了,并且包含的文件也已经被插入到.i文件里

2.2编译

就是把预处理完的文件,经过一系列词法分析,语法分析,语义分析以及优化后生成的相应的汇编代码文件,所以本质上生成的是汇编代码,现代gcc把预编译和编译两个步骤合并为一个,使用一个叫cc1的程序完成这两个步骤,执行完后,会生成汇编文件,hello.s文件

对C语言的话,是cc1

C++是cc1plus

Objective-C是cc1obj

fortran是f771

Java是jc1

实际上gcc这个命令只是这些后台程序的包装,它会根据不同的参数要求去调用预编译编译程序cc1,汇编器as,链接器Id

2.3汇编

汇编器是把汇编语言转为机器可以执行的指令,每条汇编语句都对应一个机器指令,所以汇编器的汇编过程相对于编译器来说很简单,没有复杂的语法,也没有语义,也不用指令优化

这个汇编后形成的文件叫做目标文件,是hello.o

2.4链接

为什么不汇编器直接形成可执行文件,而是形成目标文件呢,为什么要链接呢

其实我们需要把一大堆文件也就是.o文件链接起来才可以得到.out文件,就是最终的可执行文件

链接到底起个什么作用呢?

本文由作者按照 CC BY 4.0 进行授权