`
alex09
  • 浏览: 974930 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

C程序的编译过程

阅读更多
C源程序头文件-->预编译处理(cpp)-->编译程序本身-->优化程序-->汇编程序-->链接程序-->可执行文件

1.编译预处理
读取c源程序,对其中的伪指令(以#开头的指令)和特殊符号进行处理
[析] 伪指令主要包括以下四个方面
(1)宏定义指令,如#define Name TokenString,#undef等。对于前一个伪指令,预编译所要做的是将程序中的所有Name用TokenString替换,但作为字符串常量的Name则不被替换。对于后者,则将取消对某个宏的定义,使以后该串的出现不再被替换。

(2)条件编译指令,如#ifdef,#ifndef,#else,#elif,#endif,等等。这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉

(3)头文件包含指令,如#include "FileName"或者#include <FileName>等。在头文件中一般用伪指令#define定义了大量的宏(最常见的是字符常量),同时包含有各种外部符号的声明。采用头文件的目的主要是为了使某些定义可以供多个不同的C源程序使用。因为在需要用到这些定义的C源程序中,只需加上一条#include语句即可,而不必再在此文件中将这些定义重复一遍。预编译程序将把头文件中的定义统统都加入到它所产生的输出文件中,以供编译程序对之进行处理。

包含到c源程序中的头文件可以是系统提供的,这些头文件一般被放在/usr/include目录下。在程序中#include它们要使用尖括号(<>)。另外开发人员也可以定义自己的头文件,这些文件一般与c源程序放在同一目录下,此时在#include中要用双引号("")。

(4)特殊符号,预编译程序可以识别一些特殊的符号。例如在源程序中出现的LINE标识将被解释为当前行号(十进制数),FILE则被解释为当前被编译的C源程序的名称。预编译程序对于在源程序中出现的这些串将用合适的值进行替换。



    预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输出而被翻译成为机器指令。

2.编译阶段

     经过预编译得到的输出文件中,将只有常量。如数字、字符串、变量的定义,以及C语言的关键字,如main,if,else,for,while,{,},+,-,*,\,等等。预编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。

3.优化阶段
    优化处理是编译系统中一项比较艰深的技术。它涉及到的问题不仅同编译技术本身有关,而且同机器的硬件环境也有很大的关系。优化一部分是对中间代码的优化。这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的。上图中,我们将优化阶段放在编译程序的后面,这是一种比较笼统的表示。

    对于前一种优化,主要的工作是删除公共表达式、循环优化(代码外提、强度削弱、变换循环控制条件、已知量的合并等)、复写传播,以及无用赋值的删除,等等。

后一种类型的优化同机器的硬件结构密切相关,最主要的是考虑是如何充分利用机器的各个硬件寄存器存放的有关变量的值,以减少对于内存的访问次数。另外,如何根据机器硬件执行指令的特点(如流水线、RISC、CISC、VLIW等)而对指令进行一些调整使目标代码比较短,执行的效率比较高,也是一个重要的研究课题。

经过优化得到的汇编代码必须经过汇编程序的汇编转换成相应的机器指令,方可能被机器执行。

4.汇编过程

汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。

目标文件由段组成。通常一个目标文件中至少有两个段:

代码段 该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。

数据段 主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。

UNIX环境下主要有三种类型的目标文件:

(1)可重定位文件 其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。

(2)共享的目标文件 这种文件存放了适合于在两种上下文里链接的代码和数据。第一种事链接程序可把它与其它可重定位文件及共享的目标文件一起处理来创建另一个目标文件;第二种是动态链接程序将它与另一个可执行文件及其它的共享目标文件结合到一起,创建一个进程映象。

(3)可执行文件 它包含了一个可以被操作系统创建一个进程来执行之的文件。

汇编程序生成的实际上是第一种类型的目标文件。对于后两种还需要其他的一些处理方能得到,这个就是链接程序的工作了。

5.链接程序

由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。

链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够诶操作系统装入执行的统一整体。

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

(1)静态链接在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。

(2)动态链接在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。

对于可执行文件中的函数调用,可分别采用动态链接或静态链接的方法。使用动态链接能够使最终的可执行文件比较短小,并且当共享对象被多个进程使用时能节约一些内存,因为在内存中只需要保存一份此共享对象的代码。但并不是使用动态链接就一定比使用静态链接要优越。在某些情况下动态链接可能带来一些性能上损害。

经过上述五个过程,C源程序就最终被转换成可执行文件了。缺省情况下这个可执行文件的名字被命名为a.out。
分享到:
评论

相关推荐

    Linux 程序编译过程详解.docx

    "Linux 程序编译过程详解" 本文将介绍 Linux 程序编译过程的详细步骤,从高级语言到机器语言的翻译过程,包括预处理、编译、汇编和链接四个步骤。此外,还将介绍 GCC 工具链的组成部分、Binutils 的工具集、C 运行...

    程序编译过程 linux

    程序编译过程是将高级语言转化为机器语言的关键步骤,它涉及多个阶段,使得源代码能够被执行。在Linux环境中,这个过程同样适用。下面详细解析编译的四个主要阶段。 1. **编译预处理**: 编译的首步是预编译,主要...

    MTK程序编译,MTK的编译过程,以便较快的处理编译中遇到的问题,同时为以后可能的优化编译过程提供参考。

    为了更好地理解和解决在MTK程序编译过程中可能遇到的问题,以及为未来的编译优化提供指导,我们需要深入探讨这个过程。 首先,MTK程序编译的起点通常是获取源码。这通常涉及从Git仓库或其他版本控制系统中克隆项目...

    linux驱动程序编译以及应用程序编译

    编译过程中需要使用交叉编译器 arm-linux-gcc,将驱动程序编译成模块并安装到 Linux 系统中。在本文中,我们将详细介绍 Linux 驱动程序编译和应用程序编译的过程。 一、驱动程序编译成模块 驱动程序编译成模块需要...

    MTK程序编译方法 mmi程序的编译详解

    MTK(MediaTek)程序编译过程主要涉及的是如何构建基于MTK平台的应用或系统组件。本文将深入探讨MMI(Man Machine Interface)程序的编译步骤,这通常用于手机等移动设备的操作界面。 首先,我们需要了解MTK编译的...

    (完整word版)C语言程序编译常见错误对照.doc

    C语言程序编译常见错误对照是指在C语言程序编译过程中可能出现的错误类型及其对照描述。本文将详细介绍C语言程序编译常见错误对照,帮助开发者快速定位和解决编译错误。 1. fatal error C1003: error count exceeds...

    VC++程序编译连接的原理与过程.

    预处理是C++编译过程的第一步,由预处理器(cpp.exe)执行。预处理器的主要任务是处理源代码中的预处理指令,如`#include`、`#define`和`#if`等。`#include`指令用于引入其他源文件或头文件,将它们的内容合并到...

    编译原理答案(编译原理及编译程序构造)

    本资源摘要信息将对编译原理的基本概念进行详细的解释,并以编译程序的逻辑部分为主线,涵盖了编译过程的五个阶段和编译程序的七个逻辑组成部分。 首先,让我们从编译原理的基本概念开始。源程序是指由汇编语言或...

    广工 编译原理实验

    达到进一步了解程序编译过程的基本原理和基本实现方法的目的。 要求:对PL/0作以下修改扩充: 基本内容: (1)增加单词:保留字ELSE,FOR,TO,DOWNTO,RETURN;运算符 运算符 +=,-=,++,-- (2)修改单词:不等号...

    C语言pl0编译程序,功能基本完善

    达到进一步了解程序编译过程的基本原理和基本实现方法的目的。 要求:对PL/0作以下修改扩充: 基本内容: (1)增加单词: 保留字ELSE,REPEAT,UNTIL,RETURN,FOR,TO,DOWNTO等等;运算符 运算符 +=,-=,++,-- ...

    小程序反编译脚本下载,从此小程序源码就是囊中取物了

    反编译过程中,需要注意的是,微信对小程序的加密机制和保护措施也在不断升级,所以反编译结果可能不会完全与原始源码一致,可能会有部分混淆或者缺失。此外,未经许可对他人小程序进行反编译可能涉及到版权问题,...

    小程序反编译全套_JSON_wechat_wxapkg_小程序编译APP_反编译微信源码_

    本文将深入探讨微信小程序的反编译、编译过程以及相关的JSON、wxapkg等技术要点。 首先,我们要理解的是“wxapkg”文件。这是微信小程序的打包文件,包含了小程序的所有资源,如代码、图片、样式表等。当开发者完成...

    编译原理课后答案

    编译过程中涉及多种表格,如符号表、跳转表等,用于记录程序的各种信息和状态。表格管理器负责维护这些表格,确保编译过程的正确性和效率。 #### 8. 错误处理程序 错误处理是贯穿编译全过程的重要环节,它负责识别...

    微信小程序反编译(最新版).7z

    3. **恢复丢失文件**:在某些情况下,反编译过程可能会导致部分文件丢失,这个工具通过特定算法和技术可以找回这些丢失的文件。 4. **源码分析**:反编译后的源码对于学习微信小程序的开发逻辑和框架结构非常有帮助...

    微信小程序反编译脚本!

    反编译脚本通常是一个自动化的过程,涉及到多个步骤,包括但不限于: 1. **下载微信小程序的编译后的资源包**:你可以通过微信开发者工具下载一个小程序的编译版本,其中包括.jsbundle文件和其他资源。 2. **使用...

    Linux编译运行

    在Linux中,程序编译过程通常包括以下几个步骤: 1. 源文件(.c、.cpp、.cc、.cxx、.c++ 等):开发者编写的源代码文件。 2. 预处理:处理源代码中的预处理指令。 3. 编译:将预处理后的源代码编译成目标文件(.o)...

    小程序反编译工具包

    2. **命令行工具**:反编译工具通常会有一个命令行界面,用户可以输入小程序的APK或WXAPK文件路径,然后工具将自动进行反编译过程。 3. **依赖库**:可能包含Node.js模块和其他库,这些是工具运行所必需的,例如...

    Android 源码编译过程

    Android源码编译过程是Android开发中的核心环节,它涉及到一系列复杂的步骤,旨在将源代码转化为可以在Android设备上运行的二进制系统映像。这个过程对于开发者来说至关重要,因为它允许自定义和优化Android系统,以...

    vfp程序反编译

    1. **反编译原理**:反编译是将可执行程序转换回源代码的过程,它通过解析二进制代码来理解和重构程序逻辑。这个过程通常比较复杂,因为编译器在编译时会损失一些源代码的结构信息。 2. **VFP程序结构**:VFP程序由...

Global site tag (gtag.js) - Google Analytics