1.4 处理器读并解释储存在存储器中的指令
此刻,hello.c源程序已经被编译系统转换成了可执行目标文件hello,并被存放在磁盘上。
为了在Unix系统上运行该可执行文件,将它的文件名输入到称为shell的应用程序中:
shell是一种命令行解释器,它输出一个提示符,等待输入一行命令, 然后执行这个命令。
如果该命令行的第一个单词不是一个内置的shell命令,那么shell就会假设这是一个可执行文件的名字,要加载和执行该文件。
所以在此例中, shell将加载和执行hello程序,然后等待程序终止。
hello程序在屏幕上输出它的信息,然后终止。
shell随后输出一个提示符,等待下一个输入的命令行。
1.4.1 系统的硬件组成
![](https://i-blog.csdnimg.cn/blog_migrate/35a3f84fe0f55540fd2d3246879da860.png)
- 总线
贯穿整个系统的是一组电子管道,称做总线,它携带信息字节并负责在各个部件间传递。
通常总线被设计成传送定长的字节块,也就是字(word)。字中的字节数(即字长)是一个基本的系统参数,各个系统中也不尽相同。
- I/O设备
I/O(输入/输出)设备是系统与外界的联系通道。
示例系统包括四个IO设备:作为用户输入的键盘和鼠标,作为用户输出的显示器,以及用于长期存储数据和程序的磁盘驱动器(简单地说就是磁盘)。最开始,可执行程序hello就放在磁盘上。
每个I/O设备都是通过一个控制器或适配器与I/O总线连接起来的。
控制器和适配器之间的区别主要在于它们的组成方式。控制器是I/O设备本身中或是系统的主印制电路板(通常被称做主板)上的芯片组,而适配器则是一块插在主板插槽上的卡。
它们的功能都是在I/O总线和I/O设备之间传递信息。
- 主存
主存是一个临时存储设备,在处理器执行程序时,它被用来存放程序和程序处理的数据。
物理上来说,主存是由一组DRAM(动态随机存取存储器)芯片组成的。
逻辑上来说,存储器是由一个线性的字节数组组成的,每个字节都有自己惟一的地址(数组索引),这些地址是从零开始的。
一般来说,组成程序的每条机器指令都由不定量的字节构成。与C程序变量相对应的数据项的大小是根据类型变化的。
- 处理器
中央处理单元(CPU)简称处理器,是解释(或执行)存储在主存中指令的引擎。
处理器的核心是一个被称为**程序计数器(PC)**的字长大小的存储设备(或寄存器)。
在任何一个时间点上,PC都指向主存中的某条机器语言指令(内含其地址)。
从系统通电开始,直到系统断电,处理器一直在不假思索地重复执行相同的基本任务:
从程序计数器(PC)指向的存储器处读取指令,解释指令中的位,执行指令指示的简单操作,然后更新程序计数器指向下一条指令,而这条指令并不一定在存储器中和刚刚执行的指令相邻。
这样的简单操作的数目并不多,它们在主存、寄存器文件(register file)和算术逻辑单元(ALU)之间循环。
寄存器文件是一个小的存储设备,由一些字长大小的寄存器组成,这些寄存器每个都有惟一的名字。
ALU计算新的数据和地址值。
CPU在指令的要求下可能会执行以下操作:
加载: 从主存拷贝一个字节或者一个字到寄存器,覆盖寄存器原来的内容。
存储:从寄存器拷贝一个字节或者一个字到主存的某个位置,覆盖这个位置上原来的内容。
更新:拷贝两个寄存器的内容到ALU, ALU将两个字相加, 并将结果存放到一个寄存器中,覆盖该寄存器中原来的内容。
I/O读:从一个I/O设备中拷贝一个字节或者一个字到一个寄存器。
IO写:从一个寄存器中拷贝一个字节或者一个字到一个IO设备。
转移:从指令本身中抽取一个字,并将这个字拷贝到程序计数器(PC)中,覆盖PC中原来的值。
1.4.2 执行hello程序
首先,shell程序执行它的指令,等待输入命令。当我们在键盘上输入字符串“/hello”后,shell程序就逐一读取字符到寄存器,再把它存放到存储器中。
当我们在键盘上敲回车键时,shell就知道我们已经结束了命令的输入。然后shell执行一系列指令,这些指令将hello目标文件中的代码和数据从磁盘拷贝到主存,从而加载hello文件。数据包括最终会被输出的字符串“hello,world\n”。
![](https://i-blog.csdnimg.cn/blog_migrate/f3594cea31d0ace0a6f211a92d569762.png)
利用称为DMA(直接存储器存取)的技术,数据可以不通过处理器而直接从磁盘到达主存。这个步骤如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/e1e1d017699bad4e9b6abf2457ed961c.png)
一旦hello目标文件中的代码和数据被加载到了存储器,处理器就开始执行hello程序的主程序中的机器语言指令。
这些指令将“hello, world\n”串中的字节从存储器中拷贝到寄存器文件, 再从寄存器中文件拷贝到显示设备,最终显示在屏幕上。
该步骤如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/0cef195cc4ada4ac5c83c5a54e10bb4a.png)
1.5 高速缓存
系统花费了大量的时间把信息从一个地方挪到另一个地方。
大量的拷贝减慢了程序的实际工作。因此,系统设计者的一个主要目标就是使这些拷贝操作尽可能的快。
根据机械原理,较大的存储设备要比较小的存储设备运行得慢,而快速设备的造价远高于低速同类设备。
针对这种处理器与主存之间的差异,系统设计者采用了更小更快的存储设备,称为高速缓存存储器(cache memories,简称高速缓存),它们被用来作为暂时的集结区域,存放处理器在不久的将来可能会需要的信息。
1.6 形成层次结构的存储设备
在处理器和一个较大较慢的设备(例如主存)之间插入一个更小、更快的存储设备(例如,高速缓存存储器)的想法成为一个普遍的观念。
实际上,每个计算机系统中的存储设备都被组织成一个存储器层次模型,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/5451361a47f534da399d768d907d6792.png)
在这个层次模型中,从上至下,设备变得更慢、更大,并且每字节的造价也更便宜。
存储器分层结构的主要思想是一个层次上的存储器作为下一层次上的存储器的高速缓存。
参考
《深入理解计算机系统》 —— 1 计算机系统漫游