第十一章编译系统和运行系统 本章内容 C语言编译系统 预处理器、编译器、汇编器、连接器 一目标文件的格式、静态库、动态连接 。Java运行系统 无用单元收集(垃圾收集) 引入本章的目的 掌握从源程序到可执行目标程序的实际处理过程 -对实际参与软件开发是直接有用的
第十一章 编译系统和运行系统 本章内容 • C语言编译系统 –预处理器、编译器、汇编器、连接器 – 目标文件的格式、静态库、动态连接 • Java运行系统 • 无用单元收集(垃圾收集) 引入本章的目的 –掌握从源程序到可执行目标程序的实际处理过程 – 对实际参与软件开发是直接有用的
11.1 C语言编译系统 源程序 ·C源程序可以分成 预处理器 若干个模块(文件)》 分别进行预处理 修改后的源程序 、编译和汇编、形 编译器 成可重定位的目标 汇编程序 文件 ·目标文件和必要 汇编器 的库文件连接成一 可重定位的目标程序 个可执行的目标文 连接器 库 件 可重定位的 gcc和cc是编译驱 可执行的自标程序 目标文件
11.1 C语言编译系统 预处理器 源程序 修改后的源程序 可重定位的目标程序 可重定位的 目标文件 库 编译器 汇编器 汇编程序 连接器 可执行的目标程序 • C源程序可以分成 若干个模块(文件) • 分别进行预处理 、编译和汇编、形 成可重定位的目标 文件 • 目标文件和必要 的库文件连接成一 个可执行的目标文 件 • gcc和cc是编译驱 动程序的名字
11.1 C语言编译系统 main.c swap.c (1)#f1 (1)extern int buf 2]; (2)int buf[2]; (2)int *bufp0 buf; (3)#else (3)int *bufp1; (4)int buf[2]={10,20}; (4)void swap() (5)#endif (5){ (6)void swap(); (6)int temp; (7)#define A buf[O] (7)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("%od,%d",A,buf[1]); (13)return 0; (14)}
11.1 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) }
11.1 C语言编译系统 11.1.1预处理器 gcc首先调用预处理器cpp, 将源程序文件翻 译成一个ASCⅡ中间文件,它是经修改后的 源程序 cpp实现以下功能 -文件包含 -宏展开 条件编译
11.1 C语言编译系统 11.1.1 预处理器 • gcc首先调用预处理器cpp,将源程序文件翻 译成一个ASCII中间文件,它是经修改后的 源程序 • cpp实现以下功能 –文件包含 –宏展开 –条件编译
11.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 buf[2={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)swap0; (12)printf("%od,%d",A,buf[1]); (13)printf("%d,%d",buf[o],...) (13)return 0; (14)return 0; (14)} (15)
11.1 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) } 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],…); (14) return 0; (15) }
11.1 C语言编译系统 11.1.2汇编器 GCC系统的编译器cc1产生汇编代码 最简单的汇编器对输入进行两遍扫描
11.1 C语言编译系统 11.1.2 汇编器 • GCC系统的编译器cc1产生汇编代码 • 最简单的汇编器对输入进行两遍扫描
11.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:
11.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:
11.1 C语言编译系统 11.1.2汇编器 GCC系统的编译器cc1产生汇编代码 最简单的汇编器对输入进行两遍扫描 一遍扫描完成汇编代码到可重定位目标代码 的翻译也是完全可能的
11.1 C语言编译系统 11.1.2 汇编器 • GCC系统的编译器cc1产生汇编代码 • 最简单的汇编器对输入进行两遍扫描 • 一遍扫描完成汇编代码到可重定位目标代码 的翻译也是完全可能的
11.1 C语言编译系统 。例 一段汇编代码 .L2: cmpl $0,-4(%ebp) ine .L6 建.L6的▣填链 jmp .L11 L11: cmpl $0,-8(%ebp) jne .L6 加入.L6的回填链 jmp .L12 L12: jmp .L5 .p2align 4,,7 .L6: 顺L6回填链进行回填
11.1 C语言编译系统 • 例 一段汇编代码 .L2: cmpl $0,-4(%ebp) jne .L6 建.L6的回填链 jmp .L11 .L11: cmpl $0,-8(%ebp) jne .L6 加入.L6的回填链 jmp .L12 .L12: jmp .L5 .p2align 4,,7 .L6: 顺.L6回填链进行回填
11.1 C语言编译系统 11.1.2汇编器 GCC系统的编译器cc1产生汇编代码 最简单的汇编器对输入进行两遍扫描 一遍扫描完成汇编代码到可重定位目标代码 的翻译也是完全可能的 。用gcc-main.c 可以得到汇编文件main.s 用as-o main.o main.,s 可以将main.s汇编成可重定位目标文件main.o
11.1 C语言编译系统 11.1.2 汇编器 • GCC系统的编译器cc1产生汇编代码 • 最简单的汇编器对输入进行两遍扫描 • 一遍扫描完成汇编代码到可重定位目标代码 的翻译也是完全可能的 • 用 gcc −S main.c 可以得到汇编文件main.s • 用 as −o main.o main.s 可以将main.s汇编成可重定位目标文件main.o