- 1、本文档共25页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第十章编译系统和运行系统.doc
PAGE
PAGE 25
第十章 编译系统和运行系统
通常,除了编译器外,我们还需要一些其它工具的帮助,才能得到可执行的目标程序,这些工具包括预处理器、汇编器和连接器等。对于Fortran、Pascal和C来说,这些工具都较简单或明显。了解这些工具有助于我们掌握从源程序到可执行目标程序的实际处理过程,这些知识对于参与大型软件系统的开发是很有用的。本章介绍C语言编译系统。
另外,目标代码运行时,还需要一些工具的支撑,如动态连接程序、无用单元收集程序等,这些工具的集合称为运行系统。本章还介绍Java语言的运行系统及其无用单元收集程序。
10.1 C语言的编译系统
除了编译器外,我们还需要一些其它的工具来建立一个可执行的目标程序。本节以GNU C编译系统(简称GCC系统)为例,来说明程序设计语言编译系统的一般工作过程。
预处理器
源程序
修改后的源程序
可重定位的目标程序
可重定位的目标文件
库
图10.1 一个语言编译系统
编译器
汇编器
汇编程序
连接器
可执行的目标程序
一个C源程序可以分成若干个模块,存储在不同的文件中。C编译系统对这些源文件分别进行预处理、编译和汇编、形成可重定位的目标文件;然后再利用连接器将这些目标文件和必要的库文件连接成一个可执行的目标文件,即具有绝对地址的机器代码。这一过程可用图10.1描绘。
大多数编译系统提供一个驱动程序来调用语言的预处理器、编译器、汇编器、连接器,以支持用户完成从源程序到可执行程序的翻译。在GCC系统中,驱动程序的名字是gcc(或cc)。
下面我们结合一个C语言的程序实例来讨论GCC系统的工作步骤。图10.2中的程序由两个文件main.c和swap.c组成,为便于引用中间的语句,我们增加了行号。在Unix(还有Linux)环境下,键入如下命令可以得到该程序的可执行文件swap:
gcc –v –o swap main.c swap.c
这里,使用选项–v可以输出该编译系统各步骤执行的命令和执行结果,选项–o紧跟着的字符串指示生成的可执行文件的名字。
图10.2 main.c和swap.c组成的程序
main.c
(1) #if 1
(2) int buf[2];
(3) #else
(4) int buf[2] = {10,20};
(5) #endif
(6) void swap();
(7) #define A buf[0]
(8) int main()
(9) {
(10) scanf(%d, %d, buf, buf+1);
(11) swap();
(12) printf(%d, %d,A, buf[1]);
(13) return 0;
(14) }
swap.c
(1) extern int buf[2];
(2) int *bufp0 = buf;
(3) int *bufp1;
(4) void swap()
(5) {
(6) int temp;
(7) bufp1 = buf+1;
(8) temp = *bufp0;
(9) *bufp0 = *bufp1;
(10) *bufp1 = temp;
(11) }
10.1.1 预处理器
gcc首先调用预处理器cpp,将源程序文件翻译成一个ASCII中间文件,它是经修改后的源程序。图10.3是main.c经预处理后生成的中间文件main.i。
图10.3 main.i的内容
(1) # 1 “main.c”
(2)
(3) int buf[2];
(4)
(5)
(6)
(7) void swap();
(8)
(9) int main()
(10) {
(11) scanf(%d, %d, buf, buf+1);
(12) swap();
(13) printf(%d, %d,buf[0] , buf[1]);
(14) return 0;
(15) }
预处理器产生编译器的输入,它实现以下功能:
(1)文件包含 预处理器可以把源程序文件中的包含声明(#include)扩展为程序正文。例如,当源程序文件中含有语句
#include stdio.h
时,预处理器会在系统标准路径下有哪些信誉好的足球投注网站stdio.h,再用文件stdio.h中的内容来代替这个语句。
(2)宏展开 C程序中可以使用#define来定义宏,一个宏定义给出一段C代码的缩写。预处理器将源程序文件中出现的、对宏的引用展开成相应的宏定义,这一过程称为宏展开。例如,main.c的第(7)行为宏A的定义,第(12)行中的A是对该宏的引用。在预处理后产生的main.i中,宏A的定义转换成一个空行,对宏A的引用则展开成buf[0]。
(3)条件编译 预处理器根据#if和#ifdef等编译命令及其后的条件,将源程序中
文档评论(0)