我们现在有了CPU,他可以完成简单的运算,但是这还不够。
我们要编程。
2.2. 编程
程序本身就是指令的集合。
所谓的编程就是将程序员所要实现的效果,用系统支持的指令写下来。就好比给你一本唐诗三百首,让你用里面的诗句组合(杂烩)成你想要表达的意思。
当我们安装一个程序的时候,它本身实在硬盘里面的。 只有当我们启动它的时候,系统才会到硬盘里,找到该程序,然后将其读取到内存中。
将设我们还在使用一个几十年前的电脑,这个电脑每次操作只操作的数字只有八个0或者1,也就是我们常说的8位系统。这些指令被存放到内存里面之后,CPU又会把它当下要执行的那一句放到寄存器里面,然后执行这条指令。一条接一条,循环往复。
假设我们有一个8位指令。CPU得到它之后,就会分析,这一个指令里面,哪一段是操作符,哪一段是数字。比如:0101 00 11,它会读前四位,发现是加法(我瞎编的),然后读5-6位发现是0,7-8位是3,所以输出3。
CPU得到3之后,会把它放到寄存器里面,然后进行后续操作。
当然看似简单,8位操作里面的数字电路也会是无比复杂了(这还只是几十年前的科技,如今intel 64位处理器的复杂程度可见一斑)。
至此,我们已经可以编程了。我们的程序会是这样子。
00101010
10101010
01001101
01010010
计算机诞生之初,程序的确是这样的。但假如让如今的程序员来干这种事情,肯定又得哭爹喊娘一顿了(误)。所以,后来,出现了汇编语言。比如:
MOV R1, #0x1
MOV R2, #0x1
ADD R1, R2, R1
这是ARM的汇编指令,读出来如下
在寄存器R1里面装1,
在寄存器R2里面装1,
计算R1 + R2 并将值放到R1里面。
这就是一个简单的加法程序了。
但是呢,这种程序写起来还是很不舒服,效率极低。
于是高级语言语言。
int a1 = 1;
int a2 = 2;
a1 = a1 + a2;
这是c语言里面的一个简单加法。这个程序被我写完之后,会被编译出来——也就是有一个c的编译器,将这个程序转换成01010101 这样的指令(往土了说,就是个翻译机,把人类语言翻译成1&0)。当我们运行这个程序的时候,电脑会把这些东西放到内存里面,然后逐行的读取,然后一行行的运算。
好了,我们可以回归问题了。
3. CPU 对硬件的控制
3.1. 对CPU的误解
在我学习这些东西之前,我对CPU有一种误解。我以为在电脑里面,只有CPU是活的。换句话说,整个电脑里面,事无巨细,都是CPU一手操办的,就像一个勤奋的全栈工程师一样。
其实,CPU更像是个产品经理。
举个例子,我们的电脑里面有蓝牙。蓝牙里面其实也有一个CPU,更确切的说,是个MCU(Micro Control Unit),它负责将无线蓝牙信号解码成数字信号等一系列的操作,而CPU得工作只是协调MCU做相应的工作而已。
给个场景:你打开了听歌软件,输出设备是蓝牙耳机。
软件:哥,给我个耳机呗。
CPU:大妹子,耳机没插,倒是有个蓝牙耳机。
软件:那哥,你告诉蓝牙,俺要在他那里唱歌呗。
CPU:欧了。
CPU转向蓝牙。
CPU:嘿,那个傻大个,说你呢,瞅啥,俺大妹子要你给她干个活。
蓝牙:哥,你等会儿。
蓝牙:scanning devices…..
蓝牙:searching for possible peripherals providing required service…..
蓝牙:device BLEX00010EFD010 discovered…..
CPU: 啥玩样儿啊,让你干点事儿,咋这么墨迹呢?
蓝牙:哥,这事儿费神,您和大妹子多担待啊。
蓝牙:bonding with BLEX00010EFD010.
蓝牙:bonding succeeded.
蓝牙:Bluetooth Service Linkage Established.
蓝牙:哥,成了,叫大妹子开始吧。
CPU:真墨迹。
CPU转向音乐软件。
CPU:大妹子,开始吧。
软件:哥,叫他唱“我是女生,可爱的女生”。
CPU:转向蓝牙。
CPU:傻大个,唱,“我是女生,可爱的女生”。
蓝牙:check linkage lost?
蓝牙:linkage quality good.
蓝牙:signal to noise ratio: -20dB.
蓝牙:transmission rate:1 Mb/s.
蓝牙:我是女生,可爱的女生。。。。。
所以,在这个实例里面,CPU只是充当了协调&领导的角色。所以一个程序得以实现,其实仰仗于CPU能顺畅,有效的发布指令,和得到结果。
而这些信息的通道就叫 BUS,或者叫总线。
3.2. 总线(BUS)
就像上网用网线一样,电脑内部的通信也依赖于总线。这些总线传输数据,指令,地址等一系列的信息,是电脑完成各项计算和操作人物的物理基础。在计算机内部,每一个硬件设备都以特定的方式与CPU想连。哪怕是外接设备,也可以通过USB,SD卡槽得以连接。
但单单有物理基础还是不够的,就像你只有电话线,只有网线,只有天线。
你还需要一些通讯协议。
3.3 通讯协议
谁都有嘴,但并不是谁和谁都可以用嘴高效正确地传递信息。(我就发现,一和女孩子讲话,我就懵逼。) 而一门共同的语言就像是一个协议,确保双方所言所闻都能被正确的处理。总线也一样,也需要有一套既定的协议,得以让信息能在CPU和MCU之间正常往来。比较常用的协议有SPI, I2C, UART, 等等。这些协议规定了,什么指令表明什么含义,什么时候可以发信息,有几条数据线,电压多少,频率多少,等等。事无巨细,一律都有非常严谨统一的规定。
为了不让看官厌烦,我也不会跟老学究老教授一样说一堆,如果后面有空间,我可以举几个例子,这边我暂且按下不表。
4. 最终章:总结暨对这个问题的直接回复
当程序员在电脑的终端写下一行命令,比如说”turn off the bulb”(我们假设有个程序员在CPU上接出一根电线到一个小灯泡上面) 。从打下到执行有如下步骤。
我们的这句话会被编译成若干个指令,就像(瞎编):
0101 0000(翻译:CPU把0写到内存里特定的位置),
00010101(翻译:通过总线,用I2C,叫一下小灯泡的MCU),
然后小灯泡被叫了一下之后,自己到约定的这个内存为止去读数字,发现是0,所以输出0,这个0 就是个低电压,可以理解成0V,然后0V和5V与逻辑之后,就是0V,所以小灯泡就关了。
当然,我上面也纯属扯淡,这个指令不可能用短短几行代码来完成。使用I2C协议本身可能就需要超过一百条代码:通过吧某些地方的电压拉低,某些地方的电压拉高,来完成通信,有点类似黑帮片里面交易双方互相闪车灯。
5. 逻辑门的物理实现:MOSFET
有了理论上的逻辑门,现在需要做的,就是着手设计切实可用的逻辑元件。从最开始的阴极管到现在的晶体管(Transistors),在过去的大半个世纪,这些逻辑元件的实现经历了数次更新迭代。无论在速度,稳定性上,都出现了质的飞跃。
今天,我们就来讲一下MOSFET(metal–oxide–semiconductor field-effect transistor,金属氧化物场效应晶体管),它是现如今电子行业用的最多的逻辑元件,比如说我们常听到CMOS技术等等,就是基于MOSFET。
但是,在开始之前,我们必须先涉猎枯燥的,玄幻的,又非常重要的半导体理论。
5.1. 硅
一切都要从硅开始说起。
硅,其实并不稀奇。
地球上最多的元素:氧硅铝铁。这个我们都会背。
如果说没有贝尔实验室和那一群伯乐(我忘记那些科学家的名字了),可能硅还是会很平凡的,作为砂石,存在这个星球上。
硅,基于我非常有限的高中化学知识:四价,共价键,非常稳定,不易得电子,不易失电子。
除了稳定,看似没什么鸟用。但是,当少量的+3/+5价单质(如:Ga/As)被混入硅之后,我们就真的化腐朽为神奇了。
比如说,假如我们把0.1 Mol的As混入了1 Mol的Si之后,因为As为+5价,所以相比于Si,那个多出来的电子非常活跃,容易脱离原子核。这就导致一块不带电的混合物里面,有大量的(这里,大量只是相对于一块Si单质)带正电的原子核(+5As丢了一个电子)和同等量的游离电子(e)。我们称这块混合半导体为n-type(negative)。
到这里其实非常好理解。easy peasy。
同理,我们可以想象把0.1 Mol的Ga混入另外一个1 Mol的Si里面。这时候,那些牛逼的理论物理学家在这时候引入了穴的概念(Holes)。因为Ga特别容易得电子,导致有些Si的电子会被Ga偷取,留下了一些穴,而这些穴,就像+1的电子,也会不停的运动。我们称这个半导体为p-type(positive)。
然后,当我们把一个p-type 和一块n-type放在一起的时候,神奇到让人无法相信的事情发生了。
(我觉得我可能都讲不清楚~~~~~~~)
5.2. PN Junction(PN 结)
我们可以自己做一下思想实验,接触面两边邻域的电子和穴会互相中和,导致这一块区域(depletion region)的电子和穴非常稀少,而那些固定的原子核(包括带+1的As和带-1的Ga)并不会变化。他们会造成一个稳定的电场,阻止了其他地方的电子和穴涌入。于是一个动态稳定(dynamic equilibrium)形成了,如图。