我和小宇早恋了,咱们家住隔壁。程序员
晚上父母会把手机没收,但咱们还想继续聊天,又不敢发出声音,因而咱们想到了这个办法...编程
咱们把全部的中文都用灯泡的亮灭组合来表示,同时约定好每隔一秒读取一次灯泡的状态并记录下来,这是咱们的暗号。并发
我:亮亮灭灭亮app
喜:灭亮亮灭灭ide
欢:亮灭亮灭亮编码
你:亮亮亮灭灭spa
这样,咱们虽然没有了手机,依然能够日以继日地聊天,虽然效率很低,但依然很快乐。设计
我和小宇就这样在不经意间,将语言转换成为了灯泡的亮灭组合,这个过程叫作编码。blog
我和小宇就这样一直秘密保持着通话,直到上了大学,父母再也管不了咱们用手机了。内存
但这么多年的小灯泡通话,使咱们总以为事情没那么简单,因而咱们开始了一些新的探索。
咱们增长了一个开关。此时当两个开关同时闭合时,灯泡才会亮。
这样两个开关与灯泡之间,再也不是以前简单的对应关系了,而是有了逻辑。
开关的断开与闭合分别对应着电路的断开与连通。而小灯泡的不亮与亮,也分别对应着电路的断开与连通。那这二者就能够统一,再也不依赖于具体的实物表现了。
还有,开关的连通与断开,是主动的。而小灯泡的连通与断开,是被动的,是结果。
咱们把开关这里的连通与断开称为输入端,把灯泡的连通与断开称为输出端,而且将整个电路都封装在一个图形里,能够获得以下抽象:
咱们决定把这种电路叫作门电路, 上面这个叫与门。
为了从此更为抽象的探索,咱们将电路连通表示为数字 1,电路断开表示为数字 0。
咱们将这种表示方式称为二进制。
输入 A |
输入 B |
输出 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
慢慢地,咱们发现了愈来愈多的玩法。
上面这种电路,我把他抽象成以下门电路形状,叫作或门。
以后便一发不可收拾,我和小宇设计了愈来愈多的门电路,咱们发现,只要是咱们能想到的逻辑关系,均可以设计成对应的门电路。
十进制数能够转换成二进制数,而二进制数又能够对应到门电路的输入端与输出端。
因而我和小宇有了一个大胆的想法,能不能设计一个计算加法的电路呢?
咱们首先从最简单的一位二进制数相加开始:
0+0=0;0+1=1;1+0=1;1+1=10
变成一张表格以下
加数 A |
加数 B |
加和输出 |
进位输出 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
即咱们须要设计出一种电路,能够达到表中的输入与输出效果。
通过不懈努力,终于发现这个电路能够由异或门和与门两个门电路组成。
这个装置实现了二进制的一位加法,但它并不完美,由于只考虑了这两个数的进位输出,但没有考虑上一位的进位,因此只能叫半加器。
若是将前一个进位考虑进来,只需再多一个半加器,而且拼接一个或门便可。
此时咱们已经创建好了一个完美的一位加法器,并自豪地称之为全加器。
全加器作出来以后,不管多少位的加法器就均可以作出来了,只需将全加器逐个拼起来便可。咱们尝试作一个八位加法器。
OK,大功告成,有了加法器,理论上就能够实现任何的数学运算了。
由于咱们知道乘法能够转换成加法,除法能够转换成减法,而减法又能够转换成补码的加法。如今咱们能够自豪地称这个部件为,算术逻辑单元 ALU。
我和小宇都很是高兴,终于用电路的方式实现了计算功能。
但慢慢的以为没什么意思了,因而咱们又突发奇想,设计了以下诡异的电路。
当闭合开关 A 时,整个电路联通,开关 B 将会被吸下来,整个电路断开,电磁铁失去磁性,开关 B 又会弹上去,此时电路又联通,开关 B 又被吸下来。
就这样,开关 B 不断地快速地在开和闭之间循环进行,而咱们始终没有去干预这个电路,所以该电路有了自反馈的特性。
因为开关 B 的来回震荡,咱们将这种电路称为振荡器,因为它能够产生不断变化的电信号,就像时钟同样不停且规律地跑着,咱们将这个装置又称为时钟。它所产生的交替的电信号称为时钟信号。
虽然有了加法器,可是输入的数字从哪里来?能不能先保存在某个地方呢?
我和小宇通过屡次实验,发明了一个很是复杂的电路:
若是输入端为 1,改变"某控制端"信号(信号由 0 变化到 1 这个瞬间),则输出端变为 1,以后输出端仍然保持(存储)着刚刚的 1。
若是输入端为 0,改变"某控制端"信号,则输出端变为 0,以后输出端仍然保持(存储)着刚刚的 0。
若是想不明白也不要紧,只要记住这个电路的设计,实现了一位的存储功能!咱们叫它 1 位锁存器。
而后咱们把多个锁存器组合起来,再加上一些 3-8 译码器,8-1 选择器等电路,就能够实现一个能保存 8 位二进制的存储器,而且能够随机地读写它, 咱们把它叫作 RAM,简称为内存。
这个组件经过再次组合,能够造成 N × M 的 RAM 阵列。好比咱们能够表示一个 1024 * 8 的 RAM 阵列。
这表示存储容量为 1024 个单位,每一个单位占 8 位。
为了更方便地表示,咱们规定 1024 = 1K,8 位 = 1 字节(8 bit = 1 byte),那么咱们就能够说,这个 RAM 的存储容量为 1K 个单位,每一个单位占 1B。或者说,地址空间为 1K,存储容量是 1KB。
此时这个 RAM 模块已经近乎完美了,咱们甚至能够单独对其进行使用,将数据存入某个地址,将某个地址中的数据读出。
怎么方便人操做呢?只须要将地址输入、数据输入、写操做端分别接入一个控制面板,由开关来控制这些信号的输入是 1 仍是 0 便可,而后再将数据输出接入一些灯泡方便观察,这样一个单独的能够手动操做的存储装置,就搞定啦。(下图中有彩蛋~)
有了可读写的内存,咱们就能够事先把几个数字存储内存中了,接下来,咱们可否让算术逻辑单元 ALU 自动地读取这个数字,进行加法运算呢?
咱们先引入一个新的组件,10 位计数器,这里的 Clk 就接入咱们在第四部分讲的时钟信号,Clr 是清零端,具体效果下面动图一目了然。
计数器的输出就是 0,1,2,3,4,5,能够看成内存中的地址。
咱们把这个计数器,以及上面讲的 ALU 与 RAM 所有连在一块儿,尝试实现一个能够累积求和的装置。
咱们想计算的是 1+2+3+4+5+6+7, 这个自动化的计算器是这么运行的
一、用控制面板在 RAM 的地址 0~6 处存上 1~7 这几个数字的,在上一节已经实现了。
二、当计数器的值是 0 时,数据 1 被输出到加法器进行计算,此时加法器 A=1,B=0,计算结果为 1,但记住锁存器存储的是上一次的加法器输出 0,此次的计算结果要等下一次锁存器遇到上升沿信号。
三、当计数器的值是 1 时, 数据 2 被输入到加法器,此时锁存器存储了上一次的计算结果 1,并将这个 1 输出给小灯泡,并同时回传到加法器的B,因此此时加法器 A=2,B=1,计算结果为 3
四、当计数器的值是 3 时,以此类推,请看下图
咱们将累加求和这个过程自动化了!以后若是想计算累加和,只须要用控制面板事先在内存里存好数据就能够了!是否是很方便?
咱们还想要更多的自动化!
如今这个装置,只能无脑地将 RAM 中的数据从头至尾一直累加下去,没法选择加哪一个不加哪一个,也没法选择何时中止。
好比咱们 RAM 中的数据是这样的。
地址(16 进制) |
数据(10进制) |
0x00 |
... |
0x01 |
10 |
0x02 |
... |
0x03 |
20 |
0x04 |
30 |
0x05 |
... |
... |
... |
咱们只想让 RAM 蓝色地址处的数据进行累加,其余地方的数据忽略,而且到 RAM 0x05 处就中止,该怎么作呢?
咱们能够再增长一个 RAM,这个 RAM 里存放的数据,表示"指令"的含义!
咱们先发明三种指令。
add:把 RAM 这个位置处的值进行累加
nop:忽略此处的值(也就是什么都不作)
halt:中止(禁止计数器的值加一)
那么要想达到上述功能,相应的这个指令 RAM 中的数据应该是这样的。
注意:下面指令 RAM 的地址和上面数据 RAM 的地址之间有一一对应关系!
地址 (16 进制) |
指令RAM的值
|
指令含义 |
0x00 |
nop |
什么都不作 |
0x01 |
add |
累加 |
0x02 |
nop |
什么都不作 |
0x03 |
add |
累加 |
0x04 |
add |
累加 |
0x05 |
halt |
中止 |
... |
... |
... |
咱们须要引入一个控制单元,放在以下位置。
遇到 nop 指令(0x00),那输出就将锁存器的 W 位禁止,不容许锁存器写操做,这样累加结果就不会录入。
再好比遇到输入为 halt 指令(0x05),就将计数器的 EN 位禁止,不容许计数器 +1,这样就达到了中止的效果。
此时再让时钟信号震荡起来,就能够达到有选择地求和过程,而且在指定位置悬停。那如今咱们就让时钟信号震动起来,看看这个过程吧。(此处只留关键组件)
这个控制单元该怎么实现呢?咱们知道,只要给出输入,给出输出,任何组件均可以造出来。本文就再也不展开了。
有了三个指令,咱们知道了经过指令这种方式,配合各类复杂的控制器,便可实现将全部操做通通自动化。
接下来咱们须要作的,就是设计控制器,以及约定好一大堆指令,使得经过这一大堆指令的排列组合,能够实现任何自动化的计算操做。
咱们将设计好的一大堆指令
称做指令集
咱们将指令排列组合后能够实现的功能
称做程序
咱们将指令的排列组合这个过程
称做编程
咱们将排列组合这些指令的人
称做程序员
而咱们将承载这一切的装置,叫作什么呢?
没错,这个破玩意,就是
计算机
本文灵感来自一本计算机科普神做,《编码 | 隐匿在计算机软硬件背后的语言》,我在此向这本书致敬。我把核心思想提取出来,写成了低并发风格的文章,送给各位读者。若是你对计算机对总体原理十分困惑,但愿本篇文章可让你稍稍解惑。同时但愿你们找时间能够将本书通篇阅读,我保证你会颇有收获的。本文和本书的核心目的是让你理解计算机的思想,实际上如今的计算机指令与数据都是放在内存中的,文中其余地方也都是对计算机的简化模型,且不可出去真的和人家说计算机是个破玩意,尤为不准说这是低并发编程的闪客告诉你的哟~