程序编译

目录

  • 简介
  • 预处理
  • 编译
  • 汇编
  • 链接

简介

该部分内容仅作概念上的介绍,具体细节请参照《程序员的自我修养–链接、装载与库习》进行学习,以下笔记也是书中相关内容

编译过程大体可分为4个过程,预处理(preprocessing)、编译(compiliation)、汇编(assembly)和链接(linking)

使用 gcc 命令不跟任何的选项的话,会默认执行预处理、编译、汇编、链接这整个过程,如果程序没有错,就会得到一个可执行文件,默认为a.out

-E选项:提示编译器执行完预处理就停下来,后边的编译、汇编、链接就先不执行了。

-S选项:提示编译器执行完编译就停下来,不去执行汇编和链接了。

-c选项:提示编译器执行完汇编就停下来。

所以,这三个选项相当于是限定了编译器执行操作的停止时间,而不是单独的将某一步拎出来执行

预处理

  • 将所有的#define删除,并且展开所有的宏定义
  • 处理所有的条件编译指令,比如#if、#ifdef、#elif、#else、#endif
  • 处理#include预编译指令,将被包含的头文件插入到该编译指令的位置。(这个过程是递归进行的,因为被包含的文件可能还包含了其他文件)
  • 删除所有的注释///* */
  • 添加行号和文件名标识,方便后边编译时编译器产生调试用的行号心意以及编译时产生编译错误或警告时能够显示行号。
  • 保留所有的#pragma编译指令,因为编译器需要使用它们。

编译

编译过程是整个程序构建的核心部分,就是把预处理完的文件进行一系列词法分析、语法分析、语义分析以及优化后生成相应的汇编代码文件
该部分在此处不作详细介绍

汇编

汇编过程调用汇编器as来完成,是用于将汇编代码转换成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。

反汇编的含义是将机器码转换成汇编代码。

链接

链接的主要内容就是将各个模块之间相互引用的部分正确的衔接起来。它的工作就是把一些指令对其他符号地址的引用加以修正。链接过程主要包括了地址和空间分配、符号决议和重定向

  • 符号决议:有时候也被叫做符号绑定、名称绑定、名称决议、或者地址绑定,其实就是指用符号来去标识一个地址。

  • 重定位:重新计算各个目标的地址过程叫做重定位

该部分内容在后续博客中单独讲解