编译原理和技术11

上传人:子 文档编号:54400646 上传时间:2018-09-12 格式:PPT 页数:65 大小:414.50KB
返回 下载 相关 举报
编译原理和技术11_第1页
第1页 / 共65页
编译原理和技术11_第2页
第2页 / 共65页
编译原理和技术11_第3页
第3页 / 共65页
编译原理和技术11_第4页
第4页 / 共65页
编译原理和技术11_第5页
第5页 / 共65页
点击查看更多>>
资源描述

《编译原理和技术11》由会员分享,可在线阅读,更多相关《编译原理和技术11(65页珍藏版)》请在金锄头文库上搜索。

1、第十一章 编译系统和运行系统,本章内容 C语言编译系统 预处理器、汇编器、连接器 目标文件的格式、静态库、动态连接 Java运行系统 无用单元收集(垃圾收集) 掌握从源程序到可执行目标程序的实际处理过程 对实际参与软件开发是直接有用的,11.1 C语言编译系统,C源程序可以分成若干个模块 分别进行预处理、编译和汇编、形成可重定位的目标文件目标文件和必要的库文件连接成一个可执行的目标文件gcc和cc是编译驱动程序的名字,11.1 C语言编译系统,main.c (1) #if 1 (2) int buf2; (3) #else (4) int buf2 = 10,20; (5) #endif (6

2、) void swap(); (7) #define A buf0 (8) int main() (9) (10)scanf(“%d, %d“, buf, buf+1); (11)swap(); (12)printf(“%d, %d“,A, buf1); (13)return 0; (14) ,swap.c (1) extern int buf2; (2) int *bufp0 = buf; (3) int *bufp1; (4) void swap() (5) (6) int temp; (7)bufp1 = buf+1; (8)temp = *bufp0; (9)*bufp0 = *buf

3、p1; (10)*bufp1 = temp; (11) ,11.1 C语言编译系统,11.1.1 预处理器 gcc首先调用预处理器cpp,将源程序文件翻译成一个ASCII中间文件,它是经修改后的源程序 cpp实现以下功能 文件包含 宏展开 条件编译,11.1 C语言编译系统,main.c (1) #if 1 (2) int buf2; (3) #else (4) int buf2 = 10,20; (5) #endif (6) void swap(); (7) #define A buf0 (8) int main() (9) (10)scanf(“%d, %d“, buf, buf+1);

4、(11)swap(); (12)printf(“%d, %d“,A, buf1); (13)return 0; (14) ,main.i (1) # 1 “main.c” (2) (3) int buf2; (4) (5) (6) (7) void swap(); (8) (9) int main() (10) (11) scanf(“%d, %d“, buf, buf+1); (12) swap(); (13) printf(“%d,%d“,buf0, ); (14) return 0; (15) ,11.1 C语言编译系统,11.1.2 汇编器 GCC系统的编译器cc1产生汇编代码 最简单

5、的汇编器对输入进行两遍扫描 一遍扫描完成汇编代码到可重定位目标代码的翻译也是完全可能的 用 gcc S main.c 可以得到汇编文件main.s 用 as o main.o main.s 可以将main.s汇编成可重定位目标文件main.o,11.1 C语言编译系统,一段汇编代码 .L2:cmpl $0,-4(%ebp)jne .L6 jmp .L11 .L11:cmpl $0,-8(%ebp) jne .L6jmp .L12 .L12:jmp .L5 .p2align 4,7 .L6:,11.1 C语言编译系统,11.1.3 连接器目标模块或目标文件的形式 可重定位的目标文件 可执行的目标

6、文件 共享目标文件一种特殊的可重定位目标文件在装入程序或运行程序时,动态地装入到内存并连接,11.1 C语言编译系统,连接是一个收集、组织程序所需的不同代码和数据的过程,以便程序能被装入内存并被执行 连接的时机 编译时 装入时 运行时 静态连接器 动态连接器,11.1 C语言编译系统,一个重定位模块M可能定义和引用的符号 全局符号 指那些在模块M中定义,可以被其它模块引用的符号 局部符号 指那些在模块M中定义,且只能在本模块中引用的符号 外部符号 指那些由模块M引用并由其它模块定义符号 符号解析 识别各个目标模块中定义和引用的符号,为每一个符号引用确定它所关联的一个同名符号的定义 重定位,11

7、.1 C语言编译系统,11.1.4 目标文件的格式 目标文件格式随系统不同而不同 介绍Unix的ELF(Executable and Linkable Format)格式 Linux、System V Unix的后期版本、BSD Unix变体和Sun Solaris,都使用Unix的ELF格式,11.1 C语言编译系统,ELF头 描述了字的大小 产生此文件的系统的字节次序 目标文件的类型 机器类型 节头表的位置、条目多少 其它,11.1 C语言编译系统,节头表 描述目标文件中各节的位置和大小 处于目标文件的末尾,11.1 C语言编译系统,.text节被编译程序的机器代码 .rodata节诸如p

8、rintf语句中的格式串和switch语句的跳转表等只读数据 .data节已初始化的全局变量,11.1 C语言编译系统,.bss节(.comm 节)未初始化的全局变量在目标文件中不占实际的空间 .symtab节记录在该模块中定义和引用的函数和全局变量的信息的符号表,11.1 C语言编译系统,.symtab节 Type FUNC OBJECT Bind GLOBAL LOCAL EXTERN,11.1 C语言编译系统,.symtab节 Name Value 偏移地址,或 绝对地址 Size 字节数,11.1 C语言编译系统,.rel.text节.text节中需要修改的单元的位置列表 .rel.d

9、ata节用于被本模块引用或定义的全局变量的重定位信息,11.1 C语言编译系统,.debug节用于调试程序的调试符号表 .line节源文件和.text节中的机器指令之间的行号映射 .strtab一组有空结束符的串构成的串表,11.1 C语言编译系统,11.1.5 符号解析将每个符号引用正确地与某可重定位模块的符号表中的一个符号定义相关联,从而确定各个符号引用的位置 在所有输入模块中都找不到被引用符号的定义,则打印错误消息并结束连接 需要定义解析规则,11.1 C语言编译系统,解析规则函数和已初始化的全局变量称为强符号;未初始化的全局变量称为弱符号不允许有多重的强符号定义 出现一个强符号定义和多

10、个弱符号定义时,选择强符号的定义 出现多个弱符号定义时,选择任意一个弱符号的定义,11.1 C语言编译系统,11.1.6 静态库 将相关的可重定位目标模块打包成一个文件,作为连接器的输入 连接器仅复制库中被应用程序引用的模块 gcc c swap.c 编译 ar rcs mylib.a swap.o 建库 gcc static o swap1 main.c /usr/lib/libc.a mylib.a 生成可执行文件,11.1 C语言编译系统,和静态库连接,11.1 C语言编译系统,11.1.7 可执行目标文件及装入 可执行目标文件与可重定位目标文件格式类似 可执行目标文件的装入由加载器完成

11、,11.1 C语言编译系统,典型的ELF可执行目标文件,11.1 C语言编译系统,Linux运行时的内存映像,11.1 C语言编译系统,这里描述的装入过程从概念上来说是正确的 若需要了解装入过程真正是怎样工作的,必须在理解了进程、虚拟内存和内存分页等概念以后,11.1 C语言编译系统,11.1.8 动态连接 静态库周期性地被维护和更新内存可能有多份printf和scanf的代码 共享库在运行时可以装到任意的内存位置,被内存中的进程共享,11.1 C语言编译系统,共享库以两种不同的方式被共享 共享库的代码和数据被所有引用该库的可执行目标文件所共享 共享库的.text节在内存中的一个副本可以被正在

12、运行的不同进程共享,11.1 C语言编译系统,11.1 C语言编译系统,加载器通常装入和运行动态连接器动态连接器接着完成连接任务 把libc.so的文本和数据装入内存并进行重定位 把mylib.so的文本和数据装入内存并进行重定位 重定位swap2中任何对libc.so或mylib.so定义的符号的引用 将控制传递给应用程序,11.1 C语言编译系统,11.1.9 处理目标文件的一些工具 ar 创建静态库,插入、删除、罗列和提取成 strings 列出包含在目标文件中的所有可打印串 strip 从一个目标文件中删除符号表信息 nm 列出一个目标文件的符号表中定义的符号 size 列出目标文件中

13、各段的名字和大小 readelf 显示目标文件的完整结构,包括编码在ELF头中的所有信息。它包括了size和nm的功能 objdump 可以显示目标文件中的所有信息。其最有用的功能是反汇编.text节中的二进制指令 ldd 列出可执行目标文件在运行时需要的共享库,11.2 Java语言的运行系统,Java语言 简单性、分布性、安全性、可移植性等 我们关心的是:平台无关性 Java虚拟机技术是实现Java平台无关性特点的关键 Java运行系统就是Java虚拟机的一个实现,11.2 Java语言的运行系统,11.2.1 Java虚拟机语言简介Java程序首先由Java编译器把它编译成字节码, 也就

14、是JVML程序 常量池: 各种字符串常量,类似于传统程序设计语言中的符号表 类成员信息: 域信息表和方法信息表 JVML指令序列,11.2 Java语言的运行系统,Java源程序中的方法int calculate (int i)int j =2;return (i+j) (j-1);,对应的字节码程序: int calculate (int i) iconst_2 istore_2 iload_1 iload_2 iadd iload_2 iconst_1 isub imul ireturn,11.2 Java语言的运行系统,11.2.2 Java虚拟机 Java虚拟机一般由以下几个部分构成:

15、 类加载器(字节码验证器) 解释器或/和编译器 包括无用单元收集器和线程控制模块在内的运行支持系统, 另外还有一些标准类和应用接口的class文件库,11.2 Java语言的运行系统,C语言 数据栈 用来存放生存期和过程一次活动的生存期一致的局部变量 数据堆 用来存放生存期和过程一次活动的生存期不一定一致的动态变量 程序员通过malloc和free函数参与堆的管理 不安全的一个根源(悬空指针、内存泄漏) Java语言 数据栈 除对象和数组外,都分配在栈上 数据堆 对象和数组分配在堆上 出于安全的要求,程序员不参与堆管理,11.2 Java语言的运行系统,无用单元收集(俗称垃圾收集) 无用单元(

16、理论上) 那些在继续运行过程中不会再使用的数据单元 收集器采用稳妥策略 实际上并非总能判断出一个数据记录的值以后是否还需要 通过根集(roots set,在栈上)以及从根集开始的可达性来定义变量的活跃性 无用单元(实现上) 通常指那些不可能从程序变量经指针链到达的堆分配记录,11.2 Java语言的运行系统,11.2.3 即时编译器 当一个类的某个方法第一次被调用时,虚拟机才激活即时编译器将它编译成机器代码 生成的代码的执行速度可以达到解释执行的10倍 但是执行过程不得不等待编译的结束,因此使得执行时间变长 很多虚拟机都会使用快速解释器和优化编译器的组合或者是简单编译器和复杂编译器的组合,11.2 Java语言的运行系统,11.2 Java语言的运行系统,重编译机制,11.3 无用单元收集,无用单元收集器需要根据数据的活跃性来判断哪些是无用单元 活跃性分析采用稳妥策略,是通过根集以及从根集开始的可达性来定义活跃性 因此从实现的角度,无用单元是那些不可能从程序变量经指针链到达的堆分配记录 无用单元收集可能需要来自编译器、操作系统和硬件方面的支持 本节简要介绍一些主要的无用单元收集方法,并且描述编译器和收集器之间的一些相互影响,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号