一、前言
- 在我们学习C语言的时候,第一个接触的程序就是:在屏幕上打印” hello word! “,可当时的我们却未去深入的理解与感悟,一个程序代码是如何运行的;
- 而这一期的博客,则是带着我们,通过C代码去理解源文件是如何生成可执行程序。
- 首先我们得总体的知道,源文件经过编译+链接生成可执行程序;
- 编译的目的是编译器将所有的源文件,生成一个目标文件(windows中扩展名为.obj,Linux中扩展名是.o),目的是将C代码转换为计算机可识别的指令;
- 链接是链接器将所有的源文件生成的目标文件与链接库(我们可以粗浅的认为,链接库是我们声明的头文件内容的实现目的地)链接在一起;
- 编译又可分为:预处理(预编译)、编译、汇编。
二、问题探讨所使用的开发环境(只需了解现象即可)
三、翻译环境
1.预处理
- 预处理的过程,主要有以下四步:
- 将头文件全部展开,此操作是递归进行的,也代表着,可以头文件中可以包含头文件
- 将#define定义的符号与宏,全部进行替换
- 去掉所有注释,所以注释是给我们程序员自己看的
- 条件编译的处理,条件成立的代码留下,否则去掉
- 添加行号与文件名标识,方便后续生成调试信息
- 还有保留program信息
- 代码例子:
2.编译
- 编译的过程与目的:
- 将代码通过扫描器,分割一个个的符号:关键字,操作符等等,然后进行词义分析、语义分析、语法分析。主要任务是判断类型,声明。有关的语法错误,则是在此阶段完成识别并进行报错。
- 主要目的是:将C语言转换为汇编语言。
- 代码例子
3.汇编
- 汇编的过程与目的:
- 链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤
- 主要的目的是:将汇编语言转换为计算机语言。
- 代码例子:
4.链接
- 链接的目的:
- 将多个目标文件与对应的链接库进行处理,生成一个可执行程序。
四、运行环境
- 程序必须载⼊内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独⽴的环境中,程序的载⼊必须由⼿⼯安排,也可能是通过可执⾏代码置⼊只读内存来完成。
- 程序的执⾏便开始。接着便调⽤main函数。
- 开始执⾏程序代码。这个时候程序将使⽤⼀个运⾏时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使⽤静态(static)内存,存储于静态内存中的变量在程序的整个执⾏过程⼀直保留他们的值。
- 终⽌程序。正常终⽌main函数;也有可能是意外终⽌。