此文行文顺序依照《深入理解计算机系统》,其中会穿插课程内容,并非纯正的复习笔记,也并非纯正的读书笔记。
我会尽量将课程内容和考点注明出来,便于复习使用。
第一章 计算机系统漫游
1.0 序
- 计算机系统由硬件和系统软件组成,他们共同工作来运行应用程序。
1.1 信息就是位+上下文
-
程序的生命周期是从一个源程序(源文件)开始的,而源程序实际上就是一个由0和1组成的位序列,8位一组称为字节。
-
只由ascll字符组成的文件称为文本文件,所有其它文件都称为二进制文件。
-
区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。
1.2 程序被其他程序翻译成不同的格式
- 将一个源文件编译成一个可执行目标文件由编译器驱动程序完成。
1 | linux> gcc -o hello hello.c |
- gcc的翻译过程分为四个阶段,预处理器(cpp)、编译器(ccl)、汇编器(as)、链接器(ld)是分别执行这四个阶段的程序,它们一起构成了编译系统(compilation system)
四个阶段如下:
-
预处理阶段:预处理器将c源程序中的预编译指令直接插入到程序文本中,得到以.i为文件拓展名的另一个c程序。
-
编译阶段:编译器将.i文本文件转换为一个汇编语言程序的.s文件。(注:汇编语言为不同高级语言提供了一个通用的输出语言,每条语句都描述了一条低级机器语言指令。)
-
汇编阶段: 汇编器将.s翻译成机器语言指令,将指令打包成一种叫做可重定位目标程序,并将结果保存在.o文件中,.o文件是一个二进制文件。
-
链接阶段:将多个.o文件合并为一个可执行目标文件,可以被加载到内存中,由系统执行。
1.3了解编译系统如何工作十大有作用的
- 我们可以优化程序性能。
- 理解链接时出现的错误。
- 避免安全漏洞。
1.4 处理器读并解释存储在内存中的指令
-
shell是一个命令行解释器,它输出一个提示符,等待输入的命令行,执行命令。
-
shell执行可执行程序
1 | ./hello |
1.4.1 系统的硬件组成
但硬件这点破玩意看着好困好想睡
- 总线
总线是贯穿整个系统的一组电子管道,它在各个部件间传递信息字节,通常传送定长的字节块,即字(word)。字中的字节数(字长)是一个基本的系统参数,分4、8字节,即32位、64位。
- I/O设备
每个I/O设备都通过一个控制器或适配器与I/O总线相连,控制器是I/O设备本身或者系统的主印制电路板(主板)上的芯片组,而适配器则是一块插在主板插槽上的卡,他们的功能都是在设备之间传递信息。第6章详解。不知道本博还有没有第六章的笔记
第3章 程序的机器级表示
3.10 在机器级程序中将控制与数据结合起来
3.10.3 内存越界引用和缓冲区溢出
纯为复习写下如此凌乱潦草的读书笔记我人是麻的,希望有时间可以好好把这份笔记重整,满足自己的一份乐趣。
第7章 链接
-
链接是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行。链接可以执行于编译时(源代码被翻译成机器代码时),也可以执行于加载时(程序被加载器加载到内存中执行时),甚至执行于运行时(由应用程序来执行),现代系统中链接过程由链接器执行。
-
链接器将源程序分解为许多更好管理的模块,当我们改变一点时,不需要改变整个程序,只需要改变一个模块中的一点。
7.1 编译器驱动程序
-
大多数编译系统提供编译器驱动程序,它代表需要用到的预处理器、编译器、汇编器和链接器。
-
驱动程序将源文件转变为可执行文件的过程:
- 通过预处理器cpp将源.c文件转化为一个ascii码的中间.i文件
- 运行c编译器ccl将.i文件翻译成一个ascii汇编语言文件.s
- 汇编器as将.s文件转化为一个可重定位目标文件.o
- 链接器将.o及一些必要的系统文件组合起来成为一个可执行文件
- shell调用操作系统中一个叫做加载器的函数,它将可执行文件种的代码和数据复制到内存,然后将控制转移到这个程序的开头。
7.2 静态链接
-
链接器完成的两个主要任务:
-
符号解析:目标文件定义和引用符号,每个赴澳对应于一个函数、全局变量或静态变量,符号解析的目的是让每个符号引用都和一个符号定义关联起来。
-
重定位:编译器和汇编器生成从地址0开始的代码和数据节,链接器通过把每个符号定义于一个内存位置关联起来,从而重定位这些节,然后修改所有对这些符号的引用,使得它们指向这个内存位置,链接器使用汇编器产生的重定位条目的详细指令,不加甄别地执行这样的重定位。
-
-
关于连接器的一些基本事实:
- 目标文件纯粹是字节块的集合。
- 块中包含程序代码、程序数据、引导链接器和加载器的数据结构
- 链接器将块连接并修改位置
- 链接器对目标机器了解甚少
- 产生目标文件的编译器和汇编器已经完成了大部分工作
7.3 目标文件
-
目标文件的三种形式:
-
可重定位目标文件:包含二进制代码和数据,其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件
-
可执行目标文件:包含二进制代码和数据,其形式可以被直接复制到内存并执行
-
共享目标文件:一种特殊类型的可重定位目标文件,可以在加载或者运行时被动态的加载进内存并链接
-
-
编译器和汇编器生成可重定位目标文件(包括共享目标文件)。链接器生成可执行目标文件。从技术上来说,一个目标模块就是一个字节序列,而一个目标文件就是一个以文件形式存放在磁盘中的目标模块。
-
目标文件是按照特定的目标文件格式来组织的,各个系统的目标文件格式都不相同,linux使用ELF(可执行可链接格式)
7.4 可重定位目标文件
-
ELF头以一个16字节的序列开始,这个序列描述了声称该文件的系统的字的大小和字节顺序。
-
ELF头剩下的部分包含其他文件信息(ELF头的大小、目标文件类型、机器类型、节头部表的文件偏移、节头部表条目的大小和数量)
-
不同节的位置和大小都由节头部表来描述,其中目标文件每个节都有一个固定大小的条目
-
ELF可重定位文件包含以下节:
-
.text:已编译程序的机器代码。
-
.rodata:只读数据(如字符串,开关变量)
-
.data:已初始化的全局和静态C变量(局部变量保存在栈中,不出现在data中也不出现在bss中)
-
.bss:未初始化的全局和静态变量,以及所有被初始化未0的全局或静态变量
-
.symtab:存放程序中定义和引用的函数和全局变量的信息
-
.rel.text:一个.text节中位置的列表,当连接器把这个目标文件和其他文件组合时,需要修改这些位置。
-
.rel.data:被模块引用或者定义的所有全局变量的重定位信息
-
.debug:一个调试符号表,其条目是程序中定义的局部变量和类型定义,程序中定义和引用的全局变量
-
.line:原始c源程序中的行号和.text节中机器指令之间的映射
-
.strlab:包含.symtab和.debug节中的符号表,以及节头部的节名字
-
7.5 符号和符号表
-
每个可重定位目标模块m都有一个符号表,包含m定义和引用的符号的信息,在链接器的上下文中,有三种不同的符号:
- 有模块m定义并能被其他模块引用的全局符号。全局链接器符号对应于函数和全局变量。
- 由其他模块定义并能被模块m引用的全局符号。
- 只由模块m定义和引用的局部符号。他们对应于带static属性的变量和函数。
7.6 符号解析
未完待续
最近更新日期:2021-12-24