【Linux】计算机基本知识补充
目录
1.cpu
2.存储器
3.中断
1.cpu
计算机的“大脑”是CPU,它从内存中取出指令并执行之。在每个CPU基本周期中,首先从内存中取出指令,解码以确定其类型和操作数,接着执行之,然后取指、解码并执行下一条指令。按照这一方式,程序被执行完成。
每个CPU都有一套可执行的专门指令集。所以,x86处理器不能执行ARM程序,而ARM处理器也不能执行x86程序。
由于用来访问内存以得到指令或数据的时间要比执行指令花费的时间长得多,因此,所有的CPU内都有一些用来保存关键变量和临时数据的寄存器。这样,通常在指令集中提供一些指令,用以将一个字从内存调入寄存器,以及将一个字从寄存器存入内存。其他的指令可以把来自寄存器、内存的操作数组合,或者用两者产生一个结果,如将两个字相加并把结果存在寄存器或内存中。
除了用来保存变量和临时结果的通用寄存器之外,多数计算机还有一些对程序员可见的专用寄存器其中之一是程序计数器,它保存了将要取出的下一条指令的内存地址。在指令取出之后,程序计数器就被更新以便指向后继的指令。
另一个存器是堆栈指针,它指向内存中当前栈的顶端。该栈包含了每个执行过程的栈帧。一个过程的栈帧中保存了有关的输入参数、局部变量以及那些没有保存在寄存器中的临时变量。
当然还有程序状态字(ProgramStatus Word,PSW)寄存器。这个寄存器包含了条件码位(由比较指令设置)、CPU优先级、模式(用户态或内核态),以及各种其他控制位。用户程序通常读入整个PSW但是,只对其中的少量字段写入。在系统调用和IO中,PSW的作用很重要。
操作系统必须知晓所有的寄存器。在时间多路复用(timemultiplexing)CPU中,操作系统经常会中止正在运行的某个程序并启动或再启动)另一个程序。每次停止一个运行着的程序时,操作系统必须保存所有的寄存器值,这样在稍后该程序被再次运行时,可以把这些寄存器重新装入。
2.存储器
在任何一种计算机中,第二种主要部件都是存储器。
在理想情形下,存储器应该极为迅速(快于执行一条指令,这样CPU不会受到存储器的限制),充分大,并且非常便宜。但是目前的技术无法同时满足这三个目标,于是出现了不同的处理方式。
存储器系统采用一种分层次的结构,如图1-9所示。
顶层的存储器速度较高,容量较小,与底层的存储器相比每位成本较高,其差别往往是十亿数量级。
存储器系统的顶层是CPU中的寄存器。它们用与CPU相同的材料制成,所以和CPU一样快。显然,访问它们是没有时延的。其典型的存储容量是,在32位CPU中为32x32位,而在64位CPU中为64x64位。在这两种情形下,其存储容量都小于1KB。程序必须在软件中自行管理这些寄存器(即决定如何使用它们)。
下一层是高速缓存,它多数由硬件控制,主存被分割成高速缓存行(cacheline),其典型大小为64字节,地址0至63对应高速缓存行0,地址64至127对应高速缓存行1,以此类推。最常用的高速缓存行放置在CPU内部或者非常接近CPU的高速缓存中。当某个程序需要读一个存储字时,高速缓存硬件检查所需要的高速缓存行是否在高速缓存中。如果是,称为高速缓存命中,缓存满足了请求,就不需要通过总线把访问请求送往主存。高速缓存命中通常需要两个时钟周期。高速缓存未命中就必须访问内存,这要付出大量的时间代价。由于高速缓存的价格昂贵,所以其大小有限。有些机器具有两级甚至三级高速缓存,每一级高速缓存比前一级慢且容量更大。
3.中断
设备驱动程序启动设备并且让该设备在操作完成时发出一个中断。设备驱动程序在这个时刻返回。操作系统接着在需要时阻塞调用者并安排其他工作进行。当设备驱动程序检测到该设备的操作完毕时,它发出一个中断通知操作完成。
在操作系统中,中断是非常重要的,所以需要更具体地讨论。
在图1-11a中,有一个I/O的三步过程。
在第1步,设备驱动程序通过写设备寄存器通知设备控制器做什么。然后,设备控制器启动该设备。当设备控制器传送完毕被告知要进行读写的字节数量后,它在第2步中使用特定的总线发信号给中断控制器芯片。如果中断控制器已经准备接收中断(如果正忙于一个更高级的中断,也可能不接收),它会在CPU芯片的一个管脚上声明,这就是第3步。在第4步中,中断控制器把该设备的编号放到总线上,这样CPU可以读总线,并且知道哪个设备刚刚完成了操作(可能同时有许多设备在运行)。
一旦CPU决定取中断,通常程序计数器和PSW就被压入当前堆栈中,并且CPU被切换到用户态。设备编号可以成为部分内存的一个引用,用于寻找该设备中断处理程序的地址。这部分内存称为中断向量(interrupt vector)。
当中断处理程序(中断设备的设备驱动程序的一部分)开始后,它取走已入栈的程序计数器和PSW,并保存之,然后查询设备的状态。在中断处理程序全部完成之后,它返回到先前运行的用户程序中尚未执行的头一条指令。这些步骤如图1-11b所示。