---
schema_version: "library-reader-v1"
source_type: "original_book"
title: "编码 隐匿在计算机软硬件背后的语言"
author: null
edition: null
publisher: null
year: null
isbn: "9787121181184"
library_document_id: "38270854-596f-4a26-8183-db8c968c6020"
source_sha256: "249786274d83909f0bddc34d77f81ed8f0b14d1eac8843c772a37a3ecbfe2cfc"
pdf_physical_page_count: 438
pdf_physical_page_index_base: 0
range_start: 150
range_count: 10
html_url: "https://workshop.closeclaw.top/api/ai/read/38270854-596f-4a26-8183-db8c968c6020?start=150&limit=10"
markdown_url: "https://workshop.closeclaw.top/api/ai/read/38270854-596f-4a26-8183-db8c968c6020.md?start=150&limit=10"
previous_url: "https://workshop.closeclaw.top/api/ai/read/38270854-596f-4a26-8183-db8c968c6020.md?start=140&limit=10"
next_url: "https://workshop.closeclaw.top/api/ai/read/38270854-596f-4a26-8183-db8c968c6020.md?start=160&limit=10"
---

# 编码 隐匿在计算机软硬件背后的语言

> 页码规则：PDF_PHYSICAL_PAGE_INDEX 是从 0 开始的权威文件物理页索引；PRINTED_PAGE 是页面中识别出的印刷页码，可能为空，二者不得混用。

## PDF_PHYSICAL_PAGE_INDEX=150 | PRINTED_PAGE=134

只有当输入全为1时，输出才为0。

这两组等价关系就是摩根定律在电路中的实现。摩根是维多利亚女王时代的另一位数学家，比布尔大9岁，于1847年发表《形式逻辑》(FormalLogic)一书，与布尔的《逻辑的数学分析》(The Mathematical Analysis ofLogic)恰好同一天出版（据说是同一天)。实际上，布尔研究逻辑的灵感正源于一场公开的争论，这个争论就发生在摩根和另一个被指剽窃的英国数学家之间（历史最后证实摩根是清白的）。摩根很早就发现了布尔的洞察力。他无私地鼓励布尔，并帮助他开展研究，而今天除了他的这个著名定律之外，他几乎已被人们所遗忘。

摩根定律可以简单地表示为如下形式：

$$
{ \begin{array} { r } { { \overline { { \mathbf { A } } } } \times { \overline { { \mathbf { B } } } } = { \overline { { \mathbf { A } + \mathbf { B } } } } } \\ { { \overline { { \mathbf { A } } } } + { \overline { { \mathbf { B } } } } = { \overline { { \mathbf { A } \times \mathbf { B } } } } } \end{array} }
$$

A和B是两个布尔操作数。在第一个表达式中，两个操作数先被取反，再进行与运算。这与两个操作数进行或运算后再取反（即或非）的结果是一样的。在第二个表达式中，两个操作数先取反，再进行或运算，这和两个操作数先做与运算后再取反（即与非）的结果是等价的。

摩根定律是简化布尔表达式的一种重要手段，因此也可以用来简化电路。从历史的角度来说，这正是香农的论文带给电气工程师们的真正意义。但在本书中简化电路不是重点，我们关注的是让一切有效地运转而不是以最简的形式运转。我们下面要做的就是一台加法器。

编码隐匿在计算机软硬件背后的语言

134

## PDF_PHYSICAL_PAGE_INDEX=151 | PRINTED_PAGE=NOT_DETECTED

二进制加法器

加法是算术运算中最基本的运算，因此如果想搭建一台计算机（这也正是本书所隐含的内容)，那么首先就要造出可以计算两个数的和的器件。当你真正面对它时，就会发现，原来加法计算就是计算机要做的唯一工作。如果我们可以造出加法器，同样地，就可以利用加法来实现减法、乘法和除法，计算按揭付款，引导火箭飞到火星、下棋，以及填写我们的话费账单。

这一章中我们要创建的加法器与现代的计算器和计算机来比，将会很庞大、很笨拙、很慢，而且运转起来噪声不断。最有趣的是我们用来制作加法器的全部零件，都是像开关、灯泡、导线、电池、逻辑门、已经预先连接在各种逻辑门中的继电器等这些在之前的章节中学过的非常简单的电子器件。这个加法器所包含的所有器件早在120多年前就已经被发明出来了。我们并不用在房间中实际搭建出什么，相反地，可以在纸上以及我们的头脑中来搭建这个加法器。

这个加法器完全用于二进制数的计算，而且没有现代加法器那么便利。你不能使用键盘来给出需要相加的两个数，相反所要用到的是一排开关。计算结果是通过一排灯泡来显示的，而非以数字的形式来显示。

但是，这个加法器确实可以将两个数相加，其方法与计算机计算加法的方式非常相似。

## PDF_PHYSICAL_PAGE_INDEX=152 | PRINTED_PAGE=136

计算二进制数加法与计算十进制数加法非常相似。如果你想要让245和673这两个十进制数相加，你会把这个问题分解为几个简单的步骤。每个步骤只需要将两个十进制数相加。在这个例子中，首先要将5和3相加。生活中，记住加法表能更快地解决问题。

二进制数加法与十进制数加法最大的不同就在于二进制数加法中用到了一个更为简单的加法表。

如果你是一头鲸鱼并且在学校中学习了这个表格，你会大声说出：

0加0等于0;

0加1等于1；

1加0等于1；

1加1等于0，进位为1。

以上加法表可以重新写为下面带有前导零的形式，这样每个结果就都是一个2位的值。

像这样，一对二进制数相加的结果中具有两个数位，其中一位叫做加法位（sumbit)，另一位则叫做进位位（carrybit，例如，1加1等于0，进位为1）。下面我们将二进制数加法表分成两个表格，第一个是表示加法的。

第二个是表示进位的。

编码—隐匿在计算机软硬件背后的语言

136

## PDF_PHYSICAL_PAGE_INDEX=153 | PRINTED_PAGE=137

用这种方法来看二进制加法非常方便，因为在我们的加法器中加法与进位是分别进行的。搭建一个二进制加法器需要我们首先设计一个电路，通过该电路执行这些操作。完全用二进制数，问题将在很大程度上得以简化，因为，电路中的所有器件，像开关、灯泡、导线等都可以用来表示二进制数的位。

与十进制数加法一样，我们将两个二进制数字串由右向左依次逐列相加。

$$
\frac { 0 1 1 0 0 1 0 1 } { 1 0 0 0 1 1 0 1 1 0 }
$$

注意，在我们将从右边数的第3列的数相加的时候，会有一个1进位到下一列中。这在第6、第7、第8列也是一样的。

想要让多大的二进制数相加？由于仅仅在头脑中来搭建加法器，所我们可以搭建出一个能够让非常长的二进制数相加的加法器。但是经过理智的考虑之后，我们决定让搭建起来的二进制加法器最高能够执行的加法长度为8位。也就是说，我们想要相加的二进制数，其范围是从0000-0000到1111-1111，即十进制数的0到255。两个8位二进制的和最大可为1-1111-1110，即510。

加法器的控制面板如下图所示。

在这个面板中，有两排开关，每排8个。这些开关就是输入设备，我们将用它们来“输入”两个8位二进制数。在这套输入设备中，开关断开（关）即表示0，闭合（开）表示1，这与你房间墙上的开关是一样的。面板底部的输出设备是一排灯泡，共9个。这些灯泡用来显示结果。不发光的灯泡表示0，发光的灯泡表示1。这里有9个灯泡，因为两个

12 二进制加法器

137

## PDF_PHYSICAL_PAGE_INDEX=154 | PRINTED_PAGE=138

8位二进制数的相加结果可能是一个9位的二进制数。

加法器的其他部分是以各种形式连接起来的逻辑门。开关将触发逻辑门中的继电器来点亮相应的灯泡。例如，如果我们要将0110-0101和1011-0110（之前例子中的两个数）相加，则要将相应的开关置于下图所示位置。

灯泡发光显示结果为：1-0001-1011（然而，这只是一个希望的结果，因为我们还没有将加法器真正搭建出来！)

在上一章中提到过，本书中我们将会用到许多继电器。这个8位二进制加法器中所用到的继电器不少于144个，其中我们用来相加的8对二进制位，每对都需要18个继电器。如果将全部电路展示出来，你一定会崩溃的。没有人能看懂以各种方式连接起来的144个继电器所表达的意义。相反地，我们要利用逻辑门来分阶段地处理这个问题。当看到进位（两个1相加就会产生一个进位）结果表的时候，或许你已经看出来逻辑门和二进制加法的一些相关性了。

你可能意识到了，这和上一章中与门的输出结果是一样的。

因此，利用与门可以计算两个二进制数加法的进位。

到此，我们着实取得了一些进展。下面我们要做的就是利用继电器来实现下表。

编码——隐匿在计算机软硬件背后的语言

138

## PDF_PHYSICAL_PAGE_INDEX=155 | PRINTED_PAGE=139

这是在作两个二进制数加法时需要解决的另一个问题。加法位的情况并不像进位位那样简单，但是我们即将实现它。

首先我们要知道，或门和我们想要的结果很相似，除了右下角的结果。

与非门同样和我们想要的结果很相似，除了左上角的结果。

下面我们将或门和与非门连接到相同的输入上，如下图所示。

下表总结了或门和与非门的输出，并将其与我们想要的结果进行了对比。

注意，我们想要的是1，那么这种情况只有在或门和与非门的输出都为1时才会出现。这表明两个输出端可以通过一个与门连接到一起。

12 二进制加法器

139

## PDF_PHYSICAL_PAGE_INDEX=156 | PRINTED_PAGE=140

这就是我们想要的结果。

注意，在整个电路中仍然有两个输入和一个输出。两个输入同时作为或门和与非门的输入。或门和与非门的输出又分别作为一个与门的输入，最后得出了我们想要的结果。

实际上这个电路有个专门的名称，叫做异或门，简写为XOR。之所以称为异或门是因为若想其输出结果为1，要么仅让输入A为1，要么仅让输入B为1，两输入端都为1则输出为 $\scriptstyle \mathbf { 0 } _ { \circ }$ 为了不把或门、与非门和与门都画出来，我们可以使用一个电气工程师所采用的特定电气符号来表示异或门。

异或门在输入端比或门多出了一条曲线，除此之外它看上去和或门非常相像。异或门的特征如下表所示。

异或门是本书中详细介绍的最后一个逻辑门（第6个门有时会在电气工程中介绍到。它称做同或门，因为只有当两个输入相同的时候，其输出才为1。同或门所给出的输出刚好与异或门相反，因此同或门的符号和异或门相同，但在输出端多了个小圆圈)。

让我们回顾一下到目前为止所了解的内容。将两个二进制数相加将产生一个加法位和一个进位位。

编码—隐匿在计算机软硬件背后的语言

140

## PDF_PHYSICAL_PAGE_INDEX=157 | PRINTED_PAGE=1414

可以利用下面这两个逻辑门来实现这些结果。

两个二进制数相加的结果是由异或门的输出给出的，而进位位是由与门的输出给出的。  
因此我们可以将与门和异或门连在一起来计算两个二进制数（即A和B）的和。

为了避免重复画与门和异或门，你可以采用如下这种简单的表示方式。

这个符号被称为半加器(HalfAdder)。之所以叫半加器是有原因的，它将两个二进制数相加，得出一个加法位和一个进位位。但是绝大多数二进制数是多于1位的。半加器没有做到的是将之前一次的加法可能产生的进位位纳入下一次运算。例如，假设我们要将如下两个二进制数相加。

$$
\frac { 1 1 1 1 } { 1 1 1 1 }
$$

我们只能将半加器用于最右面一列的相加：1加1等于0，进位1。对于从右面算起的第二列，由于进位位的存在，实际上需要将三个二进制数相加，而随后每一列的加法都是这样的。随后的每一列二进制数相加都需要将进位位算进来。

12 二进制加法器

1414

## PDF_PHYSICAL_PAGE_INDEX=158 | PRINTED_PAGE=142

为了对三个二进制数进行加法运算，我们需要将两个半加器和一个或门做如下连接。

要理解它的工作原理，首先从最左边第一个半加器的输入A和输入B开始，其输出是一个加和及相应的进位。这个和必须与前一列的进位输入相加，然后再把它们输入到第二个半加器中。第二个半加器的输出和是最后的结果。两个半加器的进位输出又被输入到一个或门中。你可能会觉得，这里还需要一个半加法器，这当然是可行的。但是如果你了解了所有的可能性之后，你会发现，两个半加法器的进位输出是不会同时为1的。或门在这里已经足够，因为或门除了在输入都为1的时候以外，其他情况下结果和异或门结果相同。

为了避免重复地画上面的那个图，我们用以下形式来替代上图中的一堆符号，它称为全加器(Full Adder)。

以下表格总结了全加法器所有可能的输入组合以及对应的输出结果。

在本章前面曾经提到过，我们的加法器需要144个继电器。下面就来解释一下这个数目是如何得到的。每个与门、或门和与非门都需要两个继电器，因此一个异或门中就包含6个继电器。一个半加器是由一个异或门和一个与门组成的，因此一个半加器就需要8个继电器。每个全加器由两个半加器和一个或门组成，所以它要18个继电器。我们需要8个全加器来制作8位二进制加法器。因而总共需要144个继电器。

编码—隐匿在计算机软硬件背后的语言

142

## PDF_PHYSICAL_PAGE_INDEX=159 | PRINTED_PAGE=143

再来看看之前提到的由灯泡和开关所组成的控制面板。现在我们可以开始将开关和灯泡连接到全加器了。

当把两个二进制数相加时，第1列的处理方式与其他列有所不同。因为后面的几列可能包括来自前面加法的进位，而第1列不会，所以全加器的进位输入端是接地的，这表示第1列的进位输入是一个 $\scriptstyle \mathbf { 0 } _ { \circ }$ 第1列二进制数相加后很可能会产生一个进位输出，这个进位输出是下一列加法的输入。

对于接下来的两个二进制位和灯泡，可以按如下办法来连接全加器。

12 二进制加法器

143

下一段：[继续读取](https://workshop.closeclaw.top/api/ai/read/38270854-596f-4a26-8183-db8c968c6020.md?start=160&limit=10)
