从晶体管出发,计算机如何将两个数相加?理解计算机的最底层逻辑

B站影视 2025-01-19 23:38 2

摘要:芯片是计算机的核心组件,几乎所有的计算和操作都在芯片中完成。芯片由大量的晶体管组成,每一个晶体管都充当着微小的开关,控制电流的通断,从而形成二进制的“1”和“0”。这些晶体管并不孤立存在,而是按照精确的逻辑结构排列,形成逻辑门(如与、或、非等基本电路)。通过将

芯片是计算机的核心组件,几乎所有的计算和操作都在芯片中完成。芯片由大量的晶体管组成,每一个晶体管都充当着微小的开关,控制电流的通断,从而形成二进制的“1”和“0”。这些晶体管并不孤立存在,而是按照精确的逻辑结构排列,形成逻辑门(如与、或、非等基本电路)。通过将逻辑门进一步组合,构成了算术逻辑单元(ALU)和其他逻辑单元,使芯片具备了执行基本算术和逻辑运算的能力。

在计算机中,成千上万的晶体管通过巧妙的架构设计,能够并行处理大量数据,完成各种复杂任务。正是这种由下至上、层层构建的逻辑体系,使计算机不仅能执行简单的数值计算,还能处理图像、运行程序、实现智能操作。理解这些晶体管如何协同工作,是揭开计算机底层工作原理的关键。

表示和存储数字是计算机的一个重要功能,但真正的目标是计算,也就是以结构化和有目的的方式操作数字,比如将两个数字相加。这些操作由计算机的算术逻辑单元(Arithmetic and Logic Unit)处理,大多数人都称它为ALU。

ALU是计算机的“数学大脑”。理解ALU的设计和功能,你就能理解现代计算机的一个基本部分。它是计算机中完成所有计算的核心,因此几乎所有任务都需要它。

首先,看看这个漂亮的东西。

这可能是有史以来最著名的ALU——Intel 74181。它在1970年发布,是第一个完整的单芯片ALU,在当时是一项巨大的工程成就。

我们将使用布尔逻辑门来构建一个简单的ALU电路,实现与74181相同的大部分功能。

算术单元

一个ALU实际上是两个单元合一——一个算术单元一个逻辑单元。让我们先从算术单元开始,它负责处理计算机中的所有数值操作,比如加法和减法。它还执行其他一些简单操作,比如将一个数加一,这称为增量操作。

现在,我们要专注于计算机几乎所有操作的基础——将两个数字相加。我们可以完全用独立的晶体管来构建这个电路,但那样会很麻烦。

因此,我们可以使用更高层次的抽象,用逻辑门来构建组件,在这里使用的是:与、或、非和异或门。

最简单的加法电路可以将两个二进制数字相加。所以有两个输入,A和B,以及一个输出,表示这两个数字的和。A、B和输出都是单个比特。只有四种可能的输入组合。前面三种是:0+0=0,1+0=1,0+1=1。在二进制中,1等同于“真”,0等同于“假”。

这一组输入正好与异或门的布尔逻辑匹配,我们可以用它来做1比特加法器。

但第四种输入组合,1+1,是一个特殊情况。1+1等于2,但在二进制中没有2这个数字,所以结果是0,1进位到下一个列。因此,和实际上在二进制中是10。现在,异或门的输出部分正确——1加1输出0。但是,我们需要一个额外的输出线路来表示进位位。

进位位只有在两个输入都为1时才是“真”,因为这时候结果(10)大于1位能存储的值……正好我们有一个门可以实现这个功能!那就是“与门”,它只有在两个输入都为真时才输出真,所以我们也会将它加到电路中。这样就完成了,这个电路叫做“半加器(Half adder)”。

它并不复杂——只有两个逻辑门——但我们将进一步抽象,将我们刚刚制造的半加器封装为一个组件,带有两个输入——比特A和B——和两个输出,和(sum)与进位位(carry)。

这带我们进入了另一个抽象层。

全加器

如果我们想要进行比1+1更多的加法,将需要一个“全加器(full adder)”。

全加器稍微复杂一些——它需要三个输入位:A、B和C。

所以最大可能的输入是1+1+1,等于11,因此仍然只需要两个输出线路:和与进位。

我们可以用半加器来构建全加器。首先用一个半加器来加A和B,然后将结果与输入C传递给第二个半加器。最后,我们需要一个或门来检查是否有任一进位位为真。

就是这样,我们制作了一个全加器!再次,我们可以提升抽象层次,将这个全加器封装成一个组件。它接受三个输入,将它们相加,并输出和与进位(如果有的话)。

有了这些新组件,我们现在可以构建一个能够将两个8位数字(A和B)让我们从A和B的第一个位开始,称为A0和B0。此时没有进位位需要处理,因为这是第一次相加。

因此,可以用半加器来加这两个比特。输出是sum0。

现在,相加A1和B1,

因为在A0和B0的加法中可能会有进位,所以这次需要使用一个全加器,它还接受进位位作为输入。我们将这个结果输出为sum1。然后,我们将这个全加器产生的进位传递给下一个全加器,处理A2和B2。

我们继续这样依次相加,直到所有8位都相加完毕。注意,进位位会向前传递到每个后续的加法器。因此,这种结构被称为8位“进位链加法器”。

请注意,最后一个全加器有一个进位输出。如果有进位到第9位,这意味着两个数字的和太大,无法适应8位。这被称为“溢出”。

一般来说,当加法结果太大,超过了使用的比特数时,就会发生溢出。这通常会导致错误和意外行为。著名的例子是原始的《吃豆人》街机游戏用8位来记录玩家到达的关卡数。

这意味着如果玩家超过255关(8位数能表示的最大数),进入256关时,ALU会发生溢出。这导致了很多错误和故障,使得这一关无法通过。这个bug成为了顶尖吃豆人玩家的“试金石”。

为了避免溢出,我们可以扩展电路,增加更多的全加器,以允许进行16位或32位数字的加法。这样溢出发生的几率会更小,但代价是需要更多的逻辑门。另一个缺点是,每个进位需要一点时间向前传递。虽然时间非常短,只是几纳秒,但在当今高速计算机中,这已经足够产生影响了。

因此,现代计算机使用一种稍微不同的加法电路,叫做“超前进位加法器(carry-look-ahead adder)”,它更快,但最终的功能相同——还是加二进制数。

ALU的算术单元还包含其他的数学运算电路,一般来说,这些运算包括常见的8种操作。

加法(ADD):A 和 B 相加

带进位的加法(ADD with CARRY):A、B 和一个进位位一起相加

减法(SUBTRACT):B 从 A 中减去(或反过来)

带借位的减法(SUBTRACT with BORROW):B 从 A 中减去(或反过来),带借位(进位

取反(NEGATE):A 从零中减去,翻转其符号(从负到正,或正到负)

递增(INCREMENT):A 加 1

递减(DECREMENT):A 减 1

通过(PASS THROUGH):A 的所有位不变地通过

和加法器一样,这些操作都是由单个逻辑门构成的。你可能注意到这里没有乘法和除法操作。
那是因为简单的ALU没有专门的乘法和除法电路,而是通过多次加法来实现。

假设你想将12乘以5,这相当于把12加5次。因此,完成一次乘法需要通过ALU进行5次运算。这是许多简单处理器的做法,比如恒温器、电视遥控器和微波炉中的处理器。它的速度较慢,但能完成任务。

然而,更高级的处理器,比如你笔记本电脑或智能手机中的处理器,则包含带有专用乘法电路的算术单元。正如你所想,乘法电路比加法更复杂——只是需要更多的逻辑门,这也是为什么一些便宜的处理器不具备这个功能。

逻辑单元

接下来,进入ALU的另一半:逻辑单元。逻辑单元不执行算术操作,而是执行逻辑操作,比如。它还可以进行简单的数值测试,比如检查一个数是否为负数。

例如,这里有一个电路可以测试ALU的输出是否为零。

它使用一系列或门,检查是否有任何比特为1。如果其中一个比特是1,我们就知道这个数字不可能是零,然后我们用一个最终的非门来翻转这个输入,这样当输入数字为零时,输出才为1。

这就是ALU的组成的一个高层概述。我们甚至从头构建了几个主要组件,比如进位链加法器。正如你所看到的,这只是一个大规模的逻辑门组合,连接得非常巧妙。

这让我们回到开头所提到的那个ALU——Intel 74181。与今天制作的8位ALU不同,74181只能处理4位输入,这意味着你构建的ALU比这个著名的ALU还要强大一倍。

74181使用了大约70个逻辑门,不能乘法或除法。

但它在微型化方面是一个巨大的进步,为更强大、更便宜的计算机打开了大门。这个4位的ALU电路已经是很大的成就了,而8位的ALU需要数百个逻辑门才能完全构建。工程师不希望在使用ALU时看到所有这些复杂的电路,所以他们设计了一个特殊的符号来封装它,看起来像一个大写的“V”。这是另一个抽象层次!

操作

8位ALU有两个8位输入,A和B。我们还需要一种方式来指定ALU执行的操作,例如加法或减法。为此,我们使用一个4位的操作码,例如1000可能是加法命令,而1100是减法命令。基本上,操作码告诉ALU要执行什么操作。而对输入A和B进行该操作的结果是一个8位输出。

ALU还输出一系列标志位,这些是1位输出,用于表示特定状态和状态标识。

#深度好文奖励计划#

例如,如果我们将两个数字相减,结果为0,之前制作的零测试电路会将零标志设置为真(1)。这在确定两个数字是否相等时很有用。如果我们想测试A是否小于B,我们可以让ALU计算A减去B,并查看负标志是否设置为真。如果是的话,我们就知道A小于B。

最后,还有一根连到加法器的进位输出的导线,因此如果发生溢出,我们会知道。这被称为溢出标志。更高级的ALU会有更多的标志位,但这三个标志是普遍存在且经常使用的。

来源:老胡说科学

相关推荐