第8章编译系统和运行系统 本章内容 C语言编译系统 预处理器、编译器、汇编器、连接器 一目标文件的格式、静态库、动态连接 ·Java运行系统 引入本章的目的 一掌握从源程序到可执行目标程序的实际处理过程 一对实际参与软件开发是直接有用的
第8章 编译系统和运行系统 本章内容 • C语言编译系统 – 预处理器、编译器、汇编器、连接器 – 目标文件的格式、静态库、动态连接 • Java运行系统 引入本章的目的 – 掌握从源程序到可执行目标程序的实际处理过程 – 对实际参与软件开发是直接有用的
8.1 C语言编译系统 源程序 C源程序可以分成若 干个模块 预处理器 ·分别进行预处理、编 修改后的源程序 译和汇编、形成可重定 位的目标文件 编译器 ·目标文件和必要的库 汇编程序 文件连接成一个可执行 的目标文件 汇编器 gcc和cc是编译驱动 可重定位的目标程序 程序的名字 连接器 库 可重定位的 可执行的目标程序 目标文件
8 1. 1 C语言编译系统 源程序 预处理器 • C源程序可以分成若 干个模块 • 分别进行预处理、编 修改后的源程序 译和汇编 形成可重定 编译器 汇编程序 、 位的目标文件 • 目标文件和必要的库 汇编器 汇编程序 文件连接成一个可执行 的目标文件 可重定位的目标程序 汇编器 • gcc 和cc是编译驱动 可重定位的 库 连接器 程序的名字 可执行的目标程序 目标文件
8.1 C语言编译系统 main.c swap.c (1)#if1 (1)extern int buf 2]; (2)int buf 2]; (2)int *bufp0 buf; (3)#else (3)int *bufp1; (4)int buf12]={10,20}; (4)void swap() (5)#endif (5){ (6)void swap(); (6)int temp; (7)#define A buf 0] (⑦)bufp1=buf+1; (8)int main() (⑧)temp=*bufp0; (9){ (9)*bufp0 =*bufp1; (10)scanf("%d,%d",buf,buf+1); (10)*bufp1 temp; (11)} (11)swap()方 (12)printf("%d,%d",A,buf 1]); (13)return 0; (14)}
8.1 C语言编译系统 main.c ( 1 ) #if 1 swap.c ( 1 ) #if 1 ( 1 ) extern int buf[ 2 ] ; (2) int buf[2]; ( 3 ) # l ( 1 ) extern int buf[ 2 ] ; (2) int *bufp0 = buf; ( 3 ) int *bufp 1 ; ( 3 ) # e lse (4) int buf[2] = {10,20}; ( 5 ) # dif ( 3 ) int *bufp 1 ; (4) void swap( ) ( 5 ) { ( 5 ) #endif (6) void swap(); ( 7 ) #d fi A b f[ 0 ] ( 5 ) { (6) int temp; ( 7)bufp 1 = buf+ 1 ; ( 7 ) #d efine A b uf[ 0 ] (8) int main( ) ( 9 ) { ( 7)bufp 1 buf+ 1 ; (8)temp = *bufp0; ( 9 ) *bufp 0 = *bufp 1 ; ( 9 ) { (10)scanf("%d, %d", buf, buf+1); (11) ( ) ( 9) bufp 0 bufp 1 ; (10)*bufp1 = temp; (11 ) } (11 )swap ( ) ; (12)printf("%d, %d", A, buf[1]); (13) t 0 ( ) } (13 )re turn 0 ; (14) }
8.1 C语言编译系统 8.1.1预处理器 gcc首先调用预处理器cpp, 将源程序文件翻 译成一个ASCII中间文件,它是经修改后的 源程序 cpp实现以下功能 文件包含 宏展开 条件编译
8 1. C语言编译系统 8.1.1 预处理器 • gcc首先调用预处理器cpp,将源程序文件翻 将源程序文件翻 译成一个ASCII中间文件,它是经修改后的 源程序 • cpp实现以下功能 –文件包含 –宏展开 –条件编译
8.1 C语言编译系统 main.c main.i (1)#if1 (1)#1“main.c” (2)int buf 2]; (2) (3)#else (3)int buf 2]; (4)int buf12]={10,20}; (4) (5)#endif (5 (6)void swap(); (6) (7)#define A buf O] (7) void swap(); (8)int main() (8) (9){ (9)int main() (10)scanf("%d,%d",buf,buf+1) (10){ (11)swap(); (11)scanf("%d,%d",buf,buf+1); (12)swap()月 (12)printf("%d,%d",A,buf 1]); (13)printf("%d,%d",buf0],...) (13)return 0; (14)return 0; (14)} (15)
8.1 C语言编译系统 main.c ( 1 ) #if 1 main.i ( 1 ) #if 1 ( 1 ) # 1 “main c” (2) int buf[2]; ( 3 ) # l ( 1 ) # 1 “main.c” (2) ( 3 ) int buf[ 2 ] ; ( 3 ) # e lse (4) int buf[2] = {10,20}; ( 5 ) # dif ( 3 ) int buf[ 2 ] ; (4) ( 5 ) ( 5 ) #endif (6) void swap( ); ( 7 ) #d fi A b f[ 0 ] ( 5 ) (6) ( 7 ) void swap( ) ; ( 7 ) #d efine A b uf[ 0 ] (8) int main( ) ( 9 ) { ( 7 ) void swap( ) ; (8) ( 9 ) int main( ) ( 9 ) { (10)scanf("%d, %d", buf, buf+1); (11) ( ) ( 9 ) int main( ) (10) { (11 ) scanf("%d , %d" , buf, buf+1 ) ; (11 )swap ( ) ; (12)printf("%d, %d", A, buf[1]); (13) t 0 ( ) ( , , , ) ; (12) swap( ); (13 ) printf("%d ,%d" ,buf [ 0], … ) ; (13 )re turn 0 ; (14) } ( ) p ( , , [ ], ) ; (14) return 0; (15) }
8.1 C语言编译系统 8.1.2汇编器 GCC系统的编译器cc1产生汇编代码 最简单的汇编器对输入进行两遍扫描 一遍扫描完成汇编代码到可重定位目标代码 的翻译也是完全可能的 用gcc-S main..c 可以得到汇编文件main.s 。用as-0main.0main.s 可以将main.s汇编成可重定位目标文件main.0
8 1. C语言编译系统 8.1.2 汇编器 • GCC系统的编译器cc1产生汇编代码 • 最简单的汇编器对输入进行两遍扫描 • 一遍扫描完成汇编代码到可重定位目标代码 的翻译也是完全可能的 • 用 gcc S main c S main.c 可以得到 编文件 汇 main.s • 用 as o main.o main.s 可以将main.s汇编成可重定位目标文件main.o
8.1 C语言编译系统 ·例一 段汇编代码 .L2: 第一编扫描建立符号表 cmpl $0,-4(%ebp) 包括代码标号.L2、.L11 jne .L6 等 jmp .L11 第二遍扫描依据符号表 L11: 中的信息来产生可重定 cmpl $0,-8(%ebp) 位代码 jne .L6 jmp .L12 L12: jmp.L5 p2align 4,,7 L6:
8 1. 1 C语言编译系统 • 例 一段汇编代码 .L2: 第 编扫描建 符号表 一编扫描建 立符号表 , cmpl $0,-4(%ebp) 包括代码标号.L2 、.L11 j en e . L 6 等 jmp .L11 第二遍扫描依据符号表 . L11 : 中的信息来产生可重定 cmpl $0,-8(%ebp) 位代码 jne . L 6 jmp .L12 . L12 : jmp .L5 . p 2align 4,, 7 .L6:
8.1 C语言编译系统 8.1.3连接器 目标模块或目标文件的形式 可重定位的目标文件 可执行的目标文件 共享目标文件 一种特殊的可重定位目标文件 在装入程序或运行程序时,动态地装入到内存并 连接
8 1. C语言编译系统 8.1.3 连接器 目标模块或目标文件的形式 • 可重定位的目标文件 • 可执行的目标文件 • 共享目标文件 – 一种特殊的可重定位目标文件 – 在装入程序或运行程序时,动态地装入到内存并 连接
8.1 C语言编译系统 连接是一个收集、组织程序所需的不同代码和 数据的过程,以便程序能被装入内存并被执行 连接的时机 编译时 -装入时 运行时 静态连接器 动态连接器
8 1. C语言编译系统 • 连接是一个收集、组织程序所需的不同代码和 数据的过程,以便程序能被装入内存并被执行 • 连接的时机 –编译时 –装入时 –运行时 • 静态连接器 • 动态连接器
8.1 C语言编译系统 个重定位模块M可能定义和引用的符号 全局符号指那些在模块M中定义,可以被其他模 块引用的符号 局部符号指那些在模块M中定义,且只能在本模 块中引用的符号 外部符号指那些由模块M引用并由其他模块定义 的符号 符号解析 识别各个目标模块中定义和引用的符号,为每一 个符号引用确定它所关联的一个同名符号的定义 重定位
8 1. C语言编译系统 • 一个重定位模块M可能定义和引用的符号 定义和引用的符号 – 全局符号 指那些在模块M中定义,可以被其他模 块引用的符号 – 局部符号 指那些在模块M中定义,且只能在本模 块中引用的符号 – 外部符号 指那些由模块M引用并由其他模块定义 的符号 • 符号解析 – 识别各个目标模块中定义和引用的符号,为每一 个符号引用确定它所关联的一个同名符号的定义 • 重定位