c程序的创建与运行
1、序言
程序设计语言是向人以及计算机描述计算过程的记号。我们需要通过学得的程序设计语言(如C语言、JAVA等)编写程序,但在一个程序可以运行之前,需要用编译器将其翻译成一种能被计算机执行的形式(可执行目标文件)。
创建过程:预处理——>编译——>汇编——>链接
运行过程:加载
2、程序创建流程
2.1 预处理(预编译)
当我们完成源程序main.c的编写时,所编写的代码中有些数据还需要做一些处理,预处理器程序会对我们的源代码进行初步处理并翻译成一个ASCII码的中间文件main.i:
- 头文件需要展开(将#include等头文件所包括的内容,库函数全部拷贝过来)
- 宏的缩写形式需要转换为源语言的语句(将#define所定义的符号全部替换进代码中)
- 代码中注释的删除
2.2 编译
编译器会将经过预处理的源程序翻译成汇编代码main.s,因为汇编语言比较容易输出和调试。
- 词法分析(词法分析器读入组成源程序的字符流,并且将它们组织成为有意义的词素的序列)
- 语法分析(语法分析器使用由词法分析器生成的各个词法单元的第一个分量来创建树形的中间表示)
- 语义分析(使用语法树和符号表中的信息来检查源程序是否和语言定义的语义一致)
- 中间代码生成器
- 代码优化器
- 代码生成器
2.3 汇编
汇编器会将汇编程序进行处理,并生成可重定位的机器代码(可重定位目标文件)main.o。
可重定位目标文件:包含二进制代码和数据,其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件。
2.4 链接
链接是将各种代码和数据片段收集并组和成为一个单一文件(可执行目标文件)main.prog的过程,这个文件可被加载(复制)到内存并执行。
在软件开发中扮演着一个重要的角色,使得分离编译成为可能。我们不用将一个大型的应用程序组织成一个巨大的源文件,而是可以把它分解为更小、更好管理的模块,可以独立地修改和编译这些模块。当我们改变这些模块中的一个时,只需简单地重新编译它,并重新链接应用,而不必重新编译其他文件。
可执行目标文件:包含二进制代码和数据,其形式可以被直接复制到内存并执行。
构造可执行文件所需完成的任务:
- 符号解析。目标文件和引用符号,每个符号对应于一个函数、一个全局变量或者一个静态变量(即C语言中任何以static属性声明的变量)。符号解析的目的是将每个符号引用正好和一个符号定义关联起来。
- 重定位。编译器和汇编器生成从地址0开始的代码和数据节。链接器通过把每个符号定义与一个内存位置关联起来,从而从定位这些节,然后修改所有所有对这些符号的引用,使他们指向这个内存位置。