ALU 介绍

上次我们讲到了计算机如何表示和存储数字以及文字,但计算机真正的目标是进行计算、有意义地处理数字,比如把两个数字相加等等。这些事是由计算机的一个叫“算术逻辑单元(ALU)”的部件来处理的。ALU 是计算机的大脑,也是现代计算机的基石,基本上计算机所有的操作运算都会用到它。

ALU 有2单元,1个算术单元,1个逻辑单元,所以接下来分两块来分别介绍它们。

image-39
英特尔 74181,第一个封装在单个芯片内的完整 ALU

算术单元

算数单元负责计算机里所有的数字操作,比如加减法等等。要完成“将两个数相加”这个操作,需要制造出新的部件“加法器”,我们会用之前抽象出的“逻辑门”——与门、或门、非门、异或门——来进行更高层次地抽象,组装成我们想要的部件!

半加器

最简单的加法电路,就是拿两个比特(0或1)加在一起。它会有2个输入,以及1个输出:两个输入数字的和。

我们的输入和输出都只有1个比特,所以会有以下几种情形出现:

  • 0+0=0
  • 0+1=1
  • 1+0=0
  • 1+1=2=10(二进制)

注意,在二进制里没有“2”这个数字,计算出来的结果需要进位,表示为“10”。发现了什么?这4个加法结果的末尾和之前讲的“异或门”的输入输出结果一模一样!于是我们放上一个异或门:

image-40

但我们“1+1”这个运算的结果是“10”,有一个“进位”上的数字被置为了“1”,所以我们可以用之前的“与门”加入一条“进位”输出电路来保存这个进位

image-41

我们就制造出了一个“半加器”,把它进行抽象,加入我们的工具箱:

half-plus

全加器

半加器只能计算1位二进制的运算,如果超过了1位,我们就需要“全加器”。想一想我们之前的二进制计算,半加器相加后可能产生进位,那之后每一位的计算可能就会有2个对应位的数字加上“进位”的数字。因此,我们的全加器就会有3个输入,以及2个输出,它的可能性也多了许多:

image-42

我们可以利用半加器来做制作全加器,首先用一个半加器将两位数字相加,再把“进位”的数字输入另一个半加器,与前一个半加器输出的“和”进行运算,最后再用一个“或门”来监测是否有新的“进位”:

full-plus--comp-

这样就制造出了全加器!同样我们把它抽象,加入工具箱:

image-43

8位二进制加法器

接下来,让我们看看怎么制作一个8位的加法器。假设我们要把两个名字为数字“A”和数字“B”的8位二进制的数相加。

首先,我们需要一个半加器把这连个数字的最右边一位“A0”和“B0”加起来,得到一个“和”输出和一个“进位”输出。

然后下一位的数字“A1”和“B1”除了对应相加,还要加上前一位的“进位”输出,因此我们连上一个全加器,同样得到了“和”与“进位”的输出。

再将上一步的“进位”输出连入下一个全加器就可以计算下一位数字了,以此类推,就可以制造出8位二进制的加法器了:

8bitplus--comp-

注意,我们最后一位的数字计算是有“进位”的,如果两个相加的数过大,在这里产生了进位,结果超出了8位,这就叫做“溢出(overflow)”

溢出意味着结果超出了对应位数可以表示的数字,这会导致错误和不可预期的结果。例如以前在8位机上玩“吃豆人”的时候,如果你玩到了第256关(8位二进制最多可以表达0~255),那屏幕上就会出现乱码,游戏就会出错:

image-44

为了避免“溢出”,我们可以加更多的全加器来制造16位、32位、甚至64位的加法器。代价就是需要更多的逻辑门部件来制造,并且每次进位会花一些更多的时间。

其他操作

另外,除了加法,算术单元也可以进行其他的运算,大概有一下这些:

  • 加法(ADD)
  • 减法(SUBTRACT)
  • 增量+1(INCREMENT)
  • 减量-1(DECREMENT)

不同的计算也跟加法器类似,是用不同的逻辑门组合出来的。但是在其中并没有乘法或除法,因为简单的 ALU 中并没有专门的器件来处理这两个运算,而是通过重复多次的加法或减法来完成的,例如:

12*5 == 12 + 12 + 12 + 12 + 12

但是现代计算机、智能手机等更好的处理器中,为了速度更快,也加入了乘法和除法的运算单元。它们更复杂一些,但也是通过更多个逻辑门的各种组合来实现的!

逻辑单元

顾名思义,逻辑单元在计算机内负责执行逻辑操作。比如之前说的“与”,“或”,“非”,“异或”。另外,它还能做简单的数值测试,比如利用许多个“或门”,来检测一个8位数字是否为“0”:

image-45

ALU 抽象

利用大量逻辑门的组合,我们可以构建出一个 ALU。回到一开始提到的英特尔74181,它只能处理4位输入,并且不能直接进行乘除法的计算。即便如此,要构建出它,也用了70个逻辑门:

image-46

仅仅4位的 ALU 已经如此复杂了,而8位的 ALU 更是需要几百个逻辑门,因此工程师们在使用 ALU 的时候,将它抽象成了一个符号:

image-47

它接受两个操作数输入(InA,InB),以及1个表示要进行的是哪个运算的操作代码(Opcode),然后输出一个结果(Out)。

另外 ALU 还会有各种标志位(flag),来表示计算的状态。例如: 进位标志(Carry flag)表示这次计算有没有进位,0标志(Zero flag)表示这次计算的结果是不是为0,这样就可以方便地判断计算是否溢出,或者两个输入的数是否相等。高级的 ALU 中,会有更多的标志位,可以帮助处理器更快更方便地运算。

之后

目前为止,我们了解了电子计算机是如何在没有齿轮的情况下进行计算的了。接下来,我们会利用 ALU 来制造计算的 CPU(中央处理器),越来越接近我们现在的计算机了!下次见~