4.3 中央处理器
中央处理器(CPU)是计算机中进行实际计算的部分。按照我们的比喻,CPU住在市中心,城市里其他成员都是配角。CPU由许多不同的部分组成,我们将在本节介绍这些部分。
4.3.1 算术逻辑单元
算术逻辑单元(Arithmetic Logic Unit, ALU)是CPU的主要部件之一。它负责算术、布尔代数和其他运算。图4-7展示了ALU的简单结构。
图4-7 算术逻辑单元示例
操作数只是可以表示数字的位。操作码是一个数字,它告诉ALU要将哪个运算符应用于操作数。当然,结果就是我们对操作数应用运算符时得到的结果。
条件码包含与结果有关的额外信息。它们通常存储在条件码寄存器中。我们在第3章中提到过寄存器,它只是一个特殊的内存片段,与其他内存不同,它住在另一个“街道”上,那条街上有昂贵的定制住宅。典型条件码寄存器如图4-8所示。方框顶部的数字是位编号,可以很方便地指示位。注意有些位没有使用,这种情况并不罕见。
图4-8 条件码寄存器
如果最后一个操作的结果是负数,则N位被设置为1。如果最后一个操作的结果为0,则Z位被设置为1。如果最后一个操作的结果造成了溢出或下溢,O位被设置为1。
表4-1展示了ALU的具体功能。
表4-1 示例算术逻辑单元操作码
ALU可能看起来很神秘,但实际上它只是一些选择器中的逻辑门。图4-9展示了ALU的总体设计,为了简单起见省略了一些复杂的功能。
图4-9 ALU部分内部结构
4.3.2 移位寄存器
你可能已经注意到表4-1中的移位操作。左移使每一位向左移动一个位置,丢弃最左边的位,最右边的空位置移入一个0。如果把01101001(10510)左移一位,将得到11010010(21010)。这是非常方便的,因为把一个数字左移一个位后得到的数,就是把它乘以2后的数。
右移使每一位向右移动一个位置,丢弃最右边的位并将0移到最左边的空位置。如果把01101001(10510)右移1位,将得到00110100(5210)。右移一位的结果是将这个数除以2并去掉它的余数。
经常需要左移时会丢失MSB(最高有效位)值,经常需要右移时会丢失LSB(最低有效位)值,因此MSB值和LSB值保存在条件码寄存器中。我们假设CPU把这些保存在O位。
你可能已经注意到,除这些移位指令之外,ALU中的所有内容看起来都可以用组合逻辑实现。你可以用触发器来构建移位寄存器,其中的内容每计算机时钟移位一位。
顺序移位寄存器(如图4-10所示)速度很慢,在最坏的情况下它移动每位需要一个计算机时钟。
图4-10 顺序移位寄存器
我们可以通过使用逻辑构件之一的选择器(参见图2-47)完全用组合逻辑构造桶式移位器来解决这个问题。要构建一个8位移位器,我们需要8个8:1选择器。
每个位要有一个选择器,如图4-11所示。
图4-11 组合桶式移位器
右移量由S0-2提供。可以看到,在没有移位的情况下(S为000),输入位0(I0)被传递到输出位0(O0),I1传递到O1,以此类推。当S为001时,输出右移1位,因为这是输入连接到选择器的方式。当S为010时,输出右移2位,以此类推。换言之,我们有8种可能的连接方式,但只需选择一种我们想要的。
你可能会好奇为什么我一直在展示这些逻辑图。在集成电路设计系统中,类似门、多路输出选择器、多路选择器、加法器、锁存器等功能都是预先定义好的。它们的用法和旧的元件类似,只是不用把第2章提到的7400系列零件粘在电路板上,而是用设计软件把类似的元件组装成一个芯片。
你可能已经注意到我们的简单ALU中没有乘法和除法运算。那是因为乘法和除法要复杂得多,而且不能向我们展示我们还没有看到过的东西。乘法可以通过重复加法来完成,也可以通过级联桶式移位器和加法器来构建组合乘法器,但请记住左移会将数字乘以2。
移位器是实现浮点运算的一个关键元素,指数用于移动尾数以对齐二进制点,以便它们可以相加、相减等。
4.3.3 执行单元
计算机的执行单元,也称为控制单元,是计算机里的指挥中心。ALU自身并不能发挥作用,需要有指令指示它应该怎么做。执行单元从内存中正确的位置获取操作码和操作数,告诉ALU要执行哪些操作,并将结果放回内存中。希望它能以某种有用的方式完成所有这些工作。
执行单元如何做到?我们给它一个指令列表,比如“将位置10的数字与位置12的数字相加,并将结果放入位置14。”执行单元在哪里找到这些指令?在内存里!这种形式的计算机在技术上称为存储程序计算机。它起源于英国奇才艾伦·图灵(Alan Turing)(1912—1954)的作品。
是的,我们还有另一种方法来看待和解释位。指令是指示计算机做什么的位型。位型是特定CPU设计的一部分,它们不像数字那样是一些通用的标准,所以Intel Core i7 CPU对于inc A
指令的位型可能与ARM Cortex-A CPU的不同。
执行单元如何知道在内存中何处查找指令?执行单元使用一个程序计数器(Program Counter, PC),它有点像邮递员,或者像一个标有“你在这里”的大箭头。如图4-12所示,程序计数器是一个寄存器,是特殊“街道”上的一块内存。程序计数器是由一个计数器(见3.1.6节)而非一个普通寄存器(见3.1.7节)构造的。你可以将它视为具有额外计数功能的寄存器。
图4-12 程序计数器
程序计数器包含一个内存地址。换句话说,它会指向或引用内存中的一个位置。执行单元从程序计数器引用的位置获取指令。有些特殊的指令可以改变程序计数器的值。除非正在执行某个指令,否则在指令执行完毕后程序计数器值将递增(即将一条指令的大小加到其中),以便下一条指令从下一个内存位置中产生。请注意,当电源打开时,CPU有一些初始程序计数器值,通常为0。我们在图3-17中看到的计数器具有支持所有这些功能的输入。
这一切就像寻宝一样。计算机进入内存中的某个位置并找到一个“纸条”。计算机读取那张“纸条”后,会被“纸条”告知该做些什么,然后到其他地方去拿下一张“纸条”,以此类推。