文章目录

  • 前言
  • 程序的翻译环境
  • 预编译
  • 编译
  • 汇编
  • 链接

前言

在ANSI C 的任何一种实现中,存在两个不同的环境:

  • 第一种是编译环境,在这个环境下源代码被转换成可执行的机器指令。
  • 第二种是执行环境,这个环境用于实际执行代码。

本篇文章重点了解程序在编译(翻译)环境会执行的操作。

为了可以更清楚的演示过程:这里创建了两个文件:

程序的翻译环境

程序的编译也叫做程序的翻译,主要可以分为这四个步骤:预编译、编译、汇编、链接。
前面我们得到了一份C语言源代码,它包括了两个文件:main.csum.c。我们的目的是需要计算出两个数的和(也就是执行出打印出两数之和的结果)。我们将可以执行结果的文件称为可执行文件。

在Windows中C语言源代码生成的可执行文件的扩展名一般是.exe

在Linux中C语言源代码生成的可执行文件的扩展名一般是.out

要得到可执行文件。我们需要先对每一份源文件预编译、编译、汇编。执行完这三个步骤后会得到两份目标文件(扩展名为:.o)。然后链接文件以及需要的库就能够得到对应的可执行文件。

注意:如果有多个.c文件,那么编译器会单独处理每个源文件,生成各自的.obj文件,这些目标文件+链接库整体经过链接最终生成可执行程序

下面是将分别介绍这几个环节:

预编译

预编译也叫做预处理。

预处理的细节利用Linux环境可以更方便的观察到。这里利用Linux环境去观察源文件main.c在预处理阶段执行了哪些操作。

C语言源代码和对应的头文件会被预编译成一个.i文件。预处理主要是进行一些文本级的操作,包括:

  1. 展开头文件。预编译的时候会展开源文件中包含的所有头文件,例如:stdio.h

  2. 符号的替换:预编译的时候会将所有定义的宏和符号替换成对应的数据。

  3. 删除注释。

预处理后的文件不包含任何的宏定义,因为里面所有的宏都已经被替换。同样,.i文件中也已经包含了全部所需要的头文件。

编译

编译依靠的是编译器

编译过程主要进行的是:

  1. 词法分析

    词法分析会分析你的代码中的所有符号,然后产生一系列不同类型的记号:标识符、特殊符号(比如运算符号)、数字、字符串等。

  2. 语法分析

    运算符的优先级和含义也被定下来。在这个阶段,括号不匹配,缺少操作符等问题就会被编译器发现,然后报告语法错误。

  3. 语义分析

    编译器可以分析的语义是静态语义。包括声明和类型的匹配,类型的转换等。

    举例子:

    1. 当一个浮点类型的数据被赋值给整形数据时,其中隐含了一个浮点类型到整形数据的转换,语义分析的过程需要完成这个步骤。

    2. 将一个浮点值赋值给一个指针的时候,编译器会发现类型不匹配,然后报编译错误。

    动态语义一般是值在运行的时候出现的语义相关的问题,比如0作为除数时是一个运行时语义错误。

  4. 符号汇总

    在词法分析的时候我们得到了很多的符号。在整个编译与链接的过程中,我们将函数名和变量名作为他们对应的符号名。

    而编译的时候我们需要将特殊的符号汇总:

    符号汇总是有一定规则的:只会汇总函数名、全局变量和静态数据

    做完这几步后,编译器会将文件中的语言格式转换成汇编代码。

汇编

汇编是利用汇编器将汇编代码转化成机器可以执行的指令。每一个汇编指令几乎都对应了一条机器指令。

汇编后得到的文件就是目标文件。

windows环境中目标文件的后缀是.obj、在linux环境目标文件是后缀是.o

目标文件就是源代码编译后但是还没有进行链接的中间文件。

目标文件中有编译后的机器指令代码,数据。除此以外,目标文件中还有链接时需要的一些信息:符号表,调试信息,字符串等。

一般目标文件将这些信息按照不同的属性,以段segment的形式存储(一般情况下,他们都表示一个一定长度的区域)。
形成符号表

这是整个编译汇编过程中十分重要的一步。每一个文件编译完后都会有一个对应的符号表存储在目标文件中。

每一个目标文件都会有一个符号表,这个表中记录了目标文件中所用到的所有符号,每一个定义的符号有一个对应的值,叫做符号值。对于函数和变量来说这个符号值就是它们的地址。

符号表中有什么?

符号表中记录了每一个被汇总的符号,以及该符号的地址。如果这个符号是一个还没有被定义的函数名,那么这个地址就不是一个游戏地址,但是符号表中仍然有这个符号的数据。

符号表的作用在链接的时候体现。

链接

链接依靠的是链接器—为了让我们使用库函数有源头。现代的编译器可以将一个源代码编译成一个未链接的目标文件,然后由链接器将这些目标文件链接起来形成一个可执行文件。

我们的两个文件在连接前是不能够运行出结果的。因为在main函数调用sum函数的时候无法找到准确的地址。而链接的作用就可以简单理解为帮助程序去找到外部符号的地址。

怎样找到外部符号的地址呢?

链接器通过符号表的合并和符号表的重定位做到这一点。

这样在调用外部符号的时候就可以找到准确的地址了。

注意:链接的过程是很复杂的:合并符号表只是其中的一部分。需要深入了解的话建议去查阅《程序员的自我修养——链接、装载与库》。

简单认识程序的编译过程相关推荐

  1. 五分钟带你了解!Java程序的编译过程

    Java程序的编译过程 Java 语言的「编译期」其实是一段「不确定」的操作过程.因为它可能是一个前端编译器(如 Javac)把 *.java 文件编译成 *.class 文件的过程:也可能是程序运行 ...

  2. C语言程序makefile编译过程

    C语言程序makefile编译过程 2022-0111 blog_010 makefile是一些大型linux下开发的项目经常会用到的编译脚本: 可以将makefile理解为类似shell一样的脚本语 ...

  3. gcc编译c文件_Linux下C语言程序的编译过程

    Linux下C语言程序的编译过程 使用gcc编译程序时,编译工程分为4个阶段: (1)预处理:(Pre-Processing) (2)编译:(Compiling) (3)汇编:(Assembling) ...

  4. 从helloworld回顾程序的编译过程之一

    计算机中所有的文件都是以01数字形式保存的,我们常见的程序文件也是如此,以常见的入门程序Hello.c为例,其代码为代码段1所示: 代码段1 //hello.c #include <stdio. ...

  5. WPF 程序的编译过程

    基于 Sdk 的项目进行编译的时候,会使用 Sdk 中附带的 props 文件和 targets 文件对项目进行编译.Microsoft.NET.Sdk.WindowsDesktop 的 Sdk 包含 ...

  6. 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程

    一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (a ...

  7. 理解C语言(零) 导读(上):C程序的编译过程- 机器级表示

    1 从Hello world说起 Hello world是初学者使用任何一项编程语言最基本最简单的程序.下面是一个C语言版的"Helloworld" : #include < ...

  8. 开发日记-20190903 关键词 C程序gcc编译过程

    感觉挺茫然的,很多大学期间应该知道的事情,直到工作了一年了,自己才渐渐地意识到自己想要知道,要是大学期间能有人能帮助我,或许我,真的不会这么茫然吧,真的,真的.不过我也知道后悔过去,是一件多么愚蠢的事 ...

  9. java程序编译_Java程序的编译过程

    Java的编译期是一个模糊的概念,需要具体分析. 将 *.java文件转为 *.class的过程称为编译器的前端(前端编译).例如:JDK的javac编译器. 把字节码( *.class文件) 转变为 ...

最新文章

  1. java 数组存入数据库_Java中关于二维数组的理解与使用
  2. java-多线程知识
  3. 南乡子·归梦寄吴樯 [宋] 陆游
  4. 车票?工作?对象?Python 教你优雅解决年关三大难题!
  5. 计算机网络误区——为什么我的PING包发不出去?
  6. 基于 Redis 的分布式锁到底安全吗(上)?
  7. TD-SCDMA迫零块线性均衡
  8. caj转pdf python_caj2pdf gui程序: 转换 CAJ 为 PDF。佛系转换,成功与否,皆是玄学。...
  9. 高级编程技术,第三周
  10. OpenStack之八: network服务(端口9696)
  11. 氨基-八聚乙二醇Amino-PEG8-alcohol,352439-37-3
  12. MySQL Key的含义
  13. ps在html中的应用程序,Photoshop在网页设计中的应用与方法
  14. python人脸识别代码_Python不用10行代码就可实现人脸识别,还可辨别真假,太棒了!...
  15. 科技英语翻译计算机化考试,《信息科技英语翻译》期末考试 A卷参考答案.doc
  16. 基于微博评论的细粒度的虚假信息识别软件
  17. 算法训练营 重编码_我在编码训练营中的经验(以及是否适合您)
  18. 【开源项目】Imagine图片压缩工具
  19. 数据结构与算法测试题
  20. 自适应对消算法c语言,LMS自适应对消算法

热门文章

  1. Linux磁盘扩容的操作
  2. 利用黑盒测试技术设计测试用例
  3. ASIL-汽车安全完整性等级
  4. CheckBox复选框全选以及获取值(转)
  5. 北京圣思园JAVA培训教学视频汇总
  6. 用Navicat连接MySQL的安装及配置
  7. txt、csv、trc、log格式转换成asc
  8. opencv HSV 颜色模型(H通道取值 CV_BGR2HSV_FULL)
  9. 漳州市计算机报名时间,漳州市计算机操作员证怎么考要什么条件考试需要多久...
  10. htonl(), ntohl(), htons(), ntohs() 函数具体应用