first commit.

This commit is contained in:
2023-11-14 00:04:01 +08:00
commit dd23d4184d
126 changed files with 3368 additions and 0 deletions

115
docs/cs/07/index.md Normal file
View File

@@ -0,0 +1,115 @@
# 07 中央处理器
<author name="胡杰" title="20 实验 2 班 "/>
<author name="虞嘉乐" title="21 计算机 4 班 "/>
:::tip
[前去观看第七集](https://bilibili.com/BV1EW411u7th?p=7)
:::
## 计算机的心脏 —— 中央处理单元简称「CPU」
CPU 负责执行 **程序**,例如 Office浏览器游戏《半条命 2》
程序由一个个操作组成,这些操作叫做**「指令Instruction」**,指令用来告诉计算机要做什么。
## CPU 的组成
中央处理单元 —— CPU计算机的心脏**ALU**(**算术逻辑单元**)、**寄存器** 和 **RAM**(**随机存取存储器**) 组合在一起。
## 指令
CPU 负责执行程序,而程序是由 **指令** 组成的,指令负责指示计算机做什么。
打个比方,如果是数学指令(比如加减乘除)CPU 会让 ALU 进行数学计算。如果是内存指令CPU 会和内存通信,然后读/写值。
## CPU 的搭建与指令的三个阶段
CPU 有很多的组件,但这次的重点放在功能,而不是线具体怎么连。所以接下来,当我们用一条线连接两个组件的时候,这条线只是必须线路的一个表现形式。
那么,接下来就让我们正式的开始搭建吧。
首先,我们需要一些内存,把上一篇做的 RAM 拿来就可以了。为了保持简单,我们假设它只有 16 个位置,每位置有 8 位。之后再来 4 个 8 位的寄存器 A、B、C、D 用来 **临时存数据****操作数据**
我们可以给 CPU 支持的所有指令一个 ID。在下图假设的例子中我们用前四位存操作码后四位数据则来自地址或寄存器。所以我们还需要俩个寄存器来完成 CPU.一个寄存器存当前指令的内存地址,叫 **指令地址寄存器**,另一个存当前指令,叫 **指令寄存器**
![](%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221004140939.png)
### 指令的第一个阶段 —— 取指令
当我们启动计算机时,所有的寄存器从 0 开始,为了更好理解,我们过一遍在 RAM 内放的一个程序。
首先,将指令地址寄存器连到 RAM因为寄存器的值为 0因此 RAM 返回地址 0 的值,也就是 0010 1110。
0010 1110 被复制到了指令寄存器里。现在,指令拿到了,应该去处理它了,这就是 CPU 的第二个阶段 —— **解码阶段**
![](%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221004142602.png)
### 指令的第二个阶段 —— 解码
指令寄存器中,前 4 位 0010 是 LOAD_A 的指令,意思是把 RAM 的值放入寄存器 A 中。
![](%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221004143940.png)
后四位 1110 是 RAM 的地址,转换成十进制是 14.
接下来,指令由**控制单元**来解码。就像之前的所有东西一样,控制单元也是由逻辑门组成(忘记逻辑门是什么的,罚你再去看一遍[第三课](https://book.hyyz.izhai.net/cs/boolean-and-logic-gates/).
比如,为了识别 LOAD_A 的指令,我们需要一个电路,检查操作码是不是 0010我们可以用很少的逻辑门来实现。
![](%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221004144647.png)
好了,现在已经知道了什么是指令,接下来就让我们开始执行指令。
### 指令的第三个阶段 —— 执行
用检查是否是 LOAD_A 的电路打开 RAM 的 **允许读取线**,把地址 14 传过去RAM 拿到了值 0000 0011也就是十进制 3。因为我们用到的是 LOAD_A 的指令,所以我们只把这个值存在寄存器 A其他寄存器不受影响所以我们要用一根线把 RAM 连到 4 个寄存器,用电路启用寄存器 A 的 **允许写入线**,这样我们就把 RAM 地址 14 的值让在了寄存器 A 中.既然指令完成了,我们可以关掉所有线路,去拿下一个指令了。我们把指令地址寄存器加 1执行阶段就此结束
![](%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221004145957.png)
### 一个小总结
LOAD_A 只是 CPU 可执行的指令中的其中一个,不同的指令有不同的逻辑电路解码,这些逻辑电路会配置 CPU 内的组件来执行对应操作,而具体分析太过繁琐,所以有把控制单元包成一个整体,这样更加简洁。
![](%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221004150501.png)
## 第 3 个指令1000 0100
第 2 个指令与第 1 个指令大同小异,只要按部就班的走就能完成一次循环。但 RAM 的第 3 个指令和第 4 个指令与前两个稍有区别。
第三个指令(ADD)的后 4 位不是 RAM 地址,而是 2 个(数量) 2 位 (单位) 分别代表 2 个寄存器。
第一个地址是 01代表寄存器 B第二个是 00代表寄存器 A因此1000 0100 代表着把 B 的值加到 A 里,为了执行,我们用到了 ALU忘了的罚你去看[第 5 课](https://book.hyyz.izhai.net/cs/how-computers-calculate-the-alu/))。
在 ADD 指令中,先启用寄存器 B 作为 ALU 的第一个输入,然后 A 做第二个输入。之后,控制单元传递 ADD 操作码告诉 ALU 要做什么。最后的结果应当在寄存器 A 中,但不能直接放入,这回当值新值进入 ALU不断和自己相加所以控制单元会用自己的一个寄存器暂时保存结果关闭 ALU 后再写入正确的寄存器中。当然了,最后还是要把指令地址加一,这样又就完成了一个循环
![](%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_20221004153642.png)
## 最后一个指令0100 1101
这个指令是 STORE_A 指令(把寄存器 A 的值放入内存),它的后四位是 RAM 地址,但要做的不是允许读取,而是允许写入,同时打开寄存器 A 的允许读取,将 A 的值纯给 RAM。
至此,我们运行了第一个电脑程序,恭喜!
## 时钟
**时钟**,是负责管理 CPU 节奏的,它以一定的间隔发电信号,控制单元会用这个信号推进 CPU 的内部操作。当然了,节奏不能太快,因为就算是电也要一定时间来传输。
## 时钟速度
每一次指令走完三个阶段的速度叫**时钟速度**,单位是赫兹,表示频率的单位,一赫兹代表一秒一个周期。如今的处理器已经达到了几千兆赫兹。
## 超频
超频即使修改时钟速度,加快 CPU 的速度,但注意,超频太多会让 CPU 过热或产生乱码,因为信号跟不上时钟。
## 降频
当然了,既然有超频,自然有降频。降频一般用在跑新能要求较低的程序或者人已经离开时,降频能够更加省电。
为了尽可能省电,现在的处理器可以按需求加快或减慢时钟速度,这叫做动态调整频率
最后,让我们把时钟加入到我们组成的 CPU 中,这样我们的 CPU 就完整啦!现在可以放到盒子里,拿出去和你的朋友大肆炫耀了!
## 接下来
下一课,我们要加强 CPU给它拓展更多的指令同时开始讲软件。

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

BIN
docs/cs/07/目录.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB