这一章主要是通过一个最基本的C程序:
反映系统在执行这个程序时内部的大观。
1.1 信息就是位+上下文
hello程序是从一个源程序开始的。源程序实际上由0和1组成的位序列。
这里需要注意一下文本文件和二进制文件的区别。
计算机系统是一个二进制系统,系统中的一切信息都是二进制表示的,也就是说都是0和1组成的位序列,所以信息的有效解读都要依赖于上下文。
1.2 程序被其他程序翻译成不同的格式
源程序是由人类创建,供人类阅读,但机器并不行。
源程序通过其他程序翻译为低级机器语言指令,并按照可执行目标程序的格式打好包。
这个翻译过程可以分为四个阶段,即预处理阶段(预处理器),编译阶段(编译器),汇编阶段(汇编器),链接阶段(链接器)(合起来就是编译系统)。
预处理阶段
在源程序中会include很多头文件,这个阶段就是读取这些头文件,直接插入程序文本中,形成新的文件,此时的扩展名通常为.i。
编译阶段
这个阶段是做翻译工作的,把上阶段得到的文本文件翻译为.s为后缀名的文本文件,关键在于包含了一个汇编语言程序。
汇编阶段
将文本翻译为机器语言指令,并打包成可重定位目标程序,保存在.o为后缀名的二进制文件
链接阶段
这个阶段将上一阶段得到的二进制文件与一些预编译好的文件合并(例如:printf.o),生成一个可执行目标文件。
1.4 处理器读并解释存储在存储器中的指令
通过shell(一个命令行解释器)加载和运行可执行目标文件。
1.4.1 系统的硬件组成
简要地介绍系统的硬件组成
这就是系统的硬件构成,更加详细的留待以后。
但简要提一下,CPU的一些简单操作
- 加载:将一个字节或者一个字从主存复制到寄存器
- 存储:将一个字节或者一个字从寄存器复制到主存
- 操作:将两个寄存器的内容复制到ALU(算术逻辑单元)进行运算后,重新放入寄存器
- 跳转:从指令本身中抽取一个字,将字复制到程序计数器(存放下一条指令所在单元的地址)中
1.4.2 运行hello程序
外壳加载可执行的hello文件,将文件中的代码和数据从磁盘复制到主存,处理器执行main程序中的机器语言指令,将“hello world\n”字符串中的字节从主存复制到寄存器文件,再从寄存器文件复制到显示设备。
至此,hello程序的运行就基本完成了。
1.5 高速缓存至关重要
复制减缓程序“真正”的工作。
处理器从寄存器读取比主存快的多,并且差距逐渐拉大。
高速缓存存储器,用来存放处理器近期可能需要的信息,避免大量使用主存,以此加快速度。
1.6 存储设备形成层次结构
总而言之,越小越快,就越贵。
速度:寄存器>L1高速缓存>L2高速缓存>L3高速缓存主存>本地二级存储(本地磁盘)>远程二级存储。
层次结构的主要思想:高一层的存储器作为低一层的存储器的高速缓存。
1.7 操作系统管理硬件
hello程序依靠操作系统输出消息,也就是说操作系统位于应用程序和硬件之间,是一种相当底层的软件。
操作系统的两个功能:1、防止硬件被失控的应用程序滥用;2、将低级硬件设备的控制统合,变得简单一致。
操作系统至关重要的几个抽象概念:进程、虚拟存储器和文件。
1.7.1 进程
进程是操作系统对一个正在运行的程序的一种抽象。
操作系统通过交错执行(上下文切换)实现并发运行多个进程。
1.7.2 线程
一个进程可以由多个线程组成。
一个线程就是一个执行单元。
1.7.3 虚拟存储器
通过虚拟存储器,使每个进程使用一致的存储器,即虚拟地址空间。
虚拟地址空间由大量区构成:
- 程序代码和数据:运行时固定大小,从固定地址开始
- 堆:运行时可动态扩展和收缩
- 共享库:存放共享库的代码和数据
- 栈:运行时可动态扩展和收缩
- 内核虚拟存储器:常驻内存,不允许应用程序读写和调用
1.7.4 文件
文件就是字节序列
纵观这些抽象概念,不要忘记它们都是为了实现操作系统的功能而服务的,也就是说,抽象的目的是将我们从细节中解放出来,把具体而零散的工作给统一化。
1.8 系统之间利用网络通信
网络可以看作一个I/O设备。
1.9 重要主题
系统是硬件和系统软件互相交织的集合体。
1.9.1 并发和并行
1、 线程级并发
2、 指令级并发
3、 单指令、多数据并发
1.9.2 计算机系统中抽象的重要性
提供不同层次的抽象表示,来隐藏实际实现的复杂性。