# 1.5 ALU 算术逻辑单元 （How Computers Calculate）

ALU 算术逻辑单元（Arithmetic and Logic Unit）是计算机中负责运算的组件。

最著名的 ALU 之一是 Intel 74181，其于 1970 年发布，是第一个封装在单个芯片中的完整 ALU。 Intel 74181 使用了 70 个逻辑门，但无法执行乘除运算。

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2F7rHXhOePQME9nsDPQi46%2F_Intel_74181.png?alt=media&#x26;token=911639eb-3780-41eb-899e-d6cc66627e27" alt=""><figcaption><p>Intel 74181</p></figcaption></figure>

ALU 由 1 个算术单元（arithmetic）和 1 个逻辑单元（logic unit）组成，算术单元可用于进行加减法运算或是增量运算（x+1），逻辑单元执行逻辑操作（如布尔代数中的基本运算）。

## 1.5.1 算术单元

### 半加器

半加器（half adder）由异或门和与门组成，仅能计算 1 位加法。两个输入（0 或 1）有 4 种可能的输出（1 = true，0 = false），不计进位的情况（1+1=0，高位舍弃）可用「异或门」搭建：

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FyzTejz2kIehudlYRvKbp%2F%E4%B8%80%E4%BD%8D%E5%8A%A0%E6%B3%95%E5%99%A8.png?alt=media&#x26;token=6aca3ec8-0f58-4111-9016-e3bb4e6733d9" alt=""><figcaption></figcaption></figure>

当且仅当两个输入均为 1 时需要进位，该规则和「与门」相同，两者连接则为半加器：

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FaEUQdpP9sPkPRAsikz4Q%2F%E5%8D%8A%E5%8A%A0%E5%99%A8.png?alt=media&#x26;token=bd52a99d-ba7a-4b21-b264-9385cbe49ef0" alt=""><figcaption><p>半加器</p></figcaption></figure>

### 全加器

使用半加器做两个三位二进制数加法时，需要多加一个进位上的数字（共计 3 个数相加）。

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FAJSBnQpy1K0tdjU4vGtX%2Fimage.png?alt=media&#x26;token=876cb29f-7951-4607-901d-9c39d1add04d" alt=""><figcaption></figcaption></figure>

全加器的真值表如下：

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FRKEIFU8GHY1LL0OM2YfQ%2F%E5%85%A8%E5%8A%A0%E5%99%A8%E7%9C%9F%E5%80%BC%E8%A1%A8.png?alt=media&#x26;token=dbd0d9f1-e7b5-4d0f-93ee-e17dcb06ae5b" alt=""><figcaption></figcaption></figure>

全加器的逻辑门电路如下：

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FFw4LtvU6BsOrrA0bQzNu%2F%E5%85%A8%E5%8A%A0%E5%99%A8%E7%94%B5%E8%B7%AF%E5%9B%BE.png?alt=media&#x26;token=9866b5fa-3736-4bd4-a4af-4973f2033801" alt=""><figcaption></figcaption></figure>

### 8 位行波进位加法器

全加器可以处理两个三位二进制数的加法运算，两个八位二进制数的加法可以从低位逐列相加，用 1 个半加器和 7 个全加器搭建：

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2Fkcsr2qx10GDykHm3Sqyq%2F%E5%85%AB%E4%BD%8D%E8%A1%8C%E6%B3%A2%E8%BF%9B%E4%BD%8D%E5%8A%A0%E6%B3%95%E5%99%A8.png?alt=media&#x26;token=8a6c1da3-38fc-4a20-b74f-3898ae403246" alt=""><figcaption><p>八位行波进位加法器</p></figcaption></figure>

当计算结果的位数大于可用于表示的位数，则会出现「溢出」（overflow），这会导致 error 和不可预期的结果。

为防止溢出，可以使用更多的全加器来完成 16 位或是 32 位数字的操作。但使用更多的逻辑门会提高造价，同时进位计算的耗时也更多，在每秒几十亿次的运算下该延迟仍然会造成影响。所以现代计算机所采用的加法电路为「超前进位加法器」（carry-look-ahead），其速度更快。

### 乘除法

ALU 的算术单元基本都支持下图中的 8 种操作，简单 ALU 可以通过累加/累减来实现四则运算中的乘除法（慢但有效），复杂 ALU 会用更多的逻辑门构建乘法电路。

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FXG0GwZ1JpPnmge0bwIFq%2FALU%E7%AE%97%E6%9C%AF%E5%8D%95%E5%85%83%E6%94%AF%E6%8C%81%E7%9A%84%E5%85%AB%E7%A7%8D%E6%93%8D%E4%BD%9C.png?alt=media&#x26;token=8db2db1f-6c1d-4f34-9679-08d281a82cec" alt=""><figcaption><p>ALU 算术单元支持的八种操作</p></figcaption></figure>

## 1.5.2 逻辑单元

逻辑单元（logic unit）用于执行逻辑操作，比 AND、OR 和 NOT 操作，也可以用于进行简单的数值测试。注意此处的 0 和 1 遵守布尔代数的逻辑运作，而非算术加减。

下图的逻辑单元门电路用于检测输出是否为 0（可用于确认两数字是否相等），OR 或门遇 1 出 1，最后用 NOT 非门取反后，凡有 1 则为 0，检测结果为 False 假，意为输出不为 0（其中至少有一位是 1）。

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FQufjXJIxyDYhCz9hLPhf%2F%E6%A3%80%E6%B5%8B%E8%BE%93%E5%87%BA%E6%98%AF%E5%90%A6%E4%B8%BA_0_%E7%9A%84%E9%80%BB%E8%BE%91%E5%8D%95%E5%85%83%E7%94%B5%E8%B7%AF.png?alt=media&#x26;token=28a38500-ab6c-4458-97de-79be25b828cf" alt=""><figcaption><p>检测输出是否为 0 的逻辑单元电路</p></figcaption></figure>

## 1.5.3 ALU 抽象

8 位 ALU 需要用上百个逻辑门搭建，因此工程师用镂空大 V 符号来表示 ALU 组件：

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FN2dM1KbOW0vJqEWBHQl6%2Fimage.png?alt=media&#x26;token=dc94ce74-902a-40b0-a8af-da8d762af139" alt="" width="193"><figcaption><p>ALU</p></figcaption></figure>

简图如下：

<figure><img src="https://275040345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FycDQGvckh16RY095vh62%2Fuploads%2FhgXOFdWIiY2GLNRqbJwk%2F8_%E4%BD%8D_ALU_%E5%9F%BA%E6%9C%AC%E5%9B%BE%E5%BD%A2.png?alt=media&#x26;token=4a10f2b7-9029-47aa-a7b7-fba1189f246e" alt=""><figcaption><p>8 位 ALU 基本图形</p></figcaption></figure>

除了两个 8 位的输出和一个输入之外，8 位 ALU 还需要用 4-bits「操作码」（Operation Code）确认执行操作类型，同时还会输出一些 1-bit 的标志位（Flags）表示特定状态，常见类型如下：

* 溢出位（Overflow）检测是否发生溢出情况。
* 零标志位（Zero）：检测输出是否为零。
* 负标志位（Negative）：检测输出是否为负数。
