软件是如何驱动硬件的,代码是怎样对计算机实现控制的?
Java潘老师
于 2016-11-19 20:39:30 发布
阅读量3.7w
收藏
247
点赞数
88
分类专栏:
底层原理
文章标签:
计算机
软件
硬件
代码
程序
底层原理
专栏收录该内容
0 篇文章
订阅专栏
作为一名入世未深的程序员,一直很好奇编写的一行行代码是如何实现对电脑硬件的驱动,明明一个感觉是虚拟的东西,而另一个是实实在在的存在,观念上感觉压根就不是一个时空的东西,他们却偏偏能产生关系,并且能如此协调的工作着,于是便搜索相关信息,看到了比较好的解释,就借来补充一下知识面~
我们不妨从最底层开始往上走。
1. 二进制理论
众所周知,电脑,手机以及其他大量的电子设备,都是基于复杂的数字电路进行工作的。而数字电路则通过循环往复地完成一系列的指令,来输出我们想要的结果。
那究竟里面的工作原理是什么样子的呢?
首先,我们需要一套数字理论。
上帝说,我们需要一个理论。于是莱布尼茨诞生了。
莱布尼茨提出了二进制,这成为了现代计算机理论的基础。至于是老子启发了他,还是他自己坐而悟道想出了二进制,其实已经不重要了。有了二进制,一切变得简单起来:
我们可以只用1 和0 来代表所有数字,进行和十进制一样的代数运算。虽然对于人脑来说,二进制非常不雅观, 比如:
10001010101010101010 * 0101001101010 = 0101101001000001010011100110100。
但它对于计算机来说, 则最简洁,最直观,最高效。
1.1 二进制运算
每一位都只可能是1或者0,运算符号也就是加减乘除。虽然长,位数多,但速度极快!因为,但就每一位来说,运算之后,只会有几种情况:
1 + 1 -> 0, 进一位(, 这个)
1 + 0 -> 1.
0 + 1 -> 1.
0 + 0 -> 0.
所以说,《三体》中,刘慈欣讲到人肉计算机一说。单个运算单元只需要记住特定指令相对应的操作即可,甚至连加减乘除都不需要会。 但这个在现实里面并不可能完成。假设这个运算恒纪元的程序有10000条指令(但显然这个条件都不成立,因为这个程序必然很复杂,涉及复杂的浮点运算和逻辑算法,甚至还有平方开放积分微分,10000条机器代码都不够塞牙缝的), 每条指令需要100个逻辑单元,每个单元的运算时间1秒钟,那么整个程序就需要1000000s (11天13小时46分钟)。。。所以可能程序还没算完,乱纪元又来了,所有人来不及脱水都死了。这还不算发盒饭,上厕所时间。
1.2 二进制逻辑
而且,电脑可以理解是非对错了。计算机以1表示“对”,“是”,“正确”。以0表示“错”,‘否’,‘错误’。然后又引进了“或”,‘与’,‘否定’,等逻辑语句。
我们用 || 表示“或”,表示两者有一个成立即成立(我是学工科的(1) || 我是学计算机的(0) = 我没有女朋友(1))。
0 || 0 = 0
0 || 1 = 1
1 || 0 = 1
1 || 1 = 1
我们用&& 表示“与”,表示两者都成立方可成立。(我是学工科的(1)&& 我是男的(1) = 我没有女朋友(1))。
0 && 0 = 0
0 && 1 = 0
1 && 0 = 0
1 && 1 = 1
2. 数字电路的实现
2.1. 逻辑门
我们有了数字理论,那怎么才能做出逻辑电路呢?怎么才能用来运算呢?我们引入这些理想的逻辑门,靠他们来作运算。
<img src="https://i-blog.csdnimg.cn/blog_migrate/0bd4dd936ab291c1a6146b61cdebb4d9.png" data-rawwidth="341" data-rawheight="221" class="content_image" width="341">
这个就是与门,除非两个输入都是1,则输出1, 否则输出0.
<img src="https://i-blog.csdnimg.cn/blog_migrate/a9ee5689f738aaf7b688f24b2d8ee65f.png" data-rawwidth="285" data-rawheight="157" class="content_image" width="285">
这个就是或门,除非两个输入都是0,则输出0,否则输出1.
<img src="https://i-blog.csdnimg.cn/blog_migrate/3939a32943bfc4cbecb81d259fb97f44.png" data-rawwidth="333" data-rawheight="238" class="content_image" width="333">
这个就是非门,它会对输入取反(1变0,0变1 )
<img src="https://i-blog.csdnimg.cn/blog_migrate/7cb46ed363dfe0395358690b749b79cb.png" data-rawwidth="374" data-rawheight="135" class="content_image" width="374">这个叫或非电路,除非两输入相同则输出0,否则输出1
这个叫或非电路,除非两输入相同则输出0,否则输出1
现在,仅用一个理想原件,就可以做一次逻辑运算了!
那如何做代数运算?比如加法?
<img src="https://i-blog.csdnimg.cn/blog_migrate/4689734fe768360a9aa689c7299b660e.png" data-rawwidth="484" data-rawheight="278" class="origin_image zh-lightbox-thumb" width="484" data-original="https://pic4.zhimg.com/b77ceb22b8f57d384112809914dd29ab_r.jpg">以上的电路就能完成2以内的加法了。
以上的电路就能完成2以内的加法了。
当两个输入都是0, 高位输出0, 低位也是0 =》 0
当两个输入都是1, 高位输出1, 低位也是0 =》 2
当输入一个0一个1,高位输出0, 低位也是1 =》 1
所以,大家也看到了,这个逻辑电路其实并不明白加法,它只是照部就搬的给我们了碰巧正确的结果——这就是我们常说的‘中文房间’的思想实验。
我们有了2以内的加法,那么4以内也好解决了,8,16。。。以此类推,我们只要把数字电路互相叠加,就能得到很多功能,比如说加减乘除,求余等等数学运算,相应地,逻辑电路也会越来越复杂:
<img src="https://i-blog.csdnimg.cn/blog_migrate/36afbb3ba2066d870fd58ec580818231.png" data-rawwidth="1440" data-rawheight="544" class="origin_image zh-lightbox-thumb" width="1440" data-original="https://pic4.zhimg.com/4009eac737796376f4d93af69ec4eaff_r.jpg">
我们现在有了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卡槽得以连接。
但单单有物理基础还是不够的,就像你只有电话线,只有网线,只有天线。
你还需要一些通讯协议。
4.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)形成了,如图。
<img src="https://i-blog.csdnimg.cn/blog_migrate/4ad2ed2150c27df23eebb492c35249bf.png" data-rawwidth="661" data-rawheight="248" class="origin_image zh-lightbox-thumb" width="661" data-original="https://pic4.zhimg.com/d31a4e375bf257d8b4dd1ac86ccc7f9b_r.png">为了看官不头疼,这里我省去若干章节。总而言之,言而总之。到这里,我们就得到了一个二极管。
为了看官不头疼,这里我省去若干章节。总而言之,言而总之。到这里,我们就得到了一个二极管。
当我们施加一个正向电压的时候,depletion region会因为电压的缘故变薄,大量的电子和穴得以穿过,造成很强的电流。而当我们施加一个反向电压的时候,depletion region会变厚,电流无法通过。
wah lah ~
5.3. 场效应晶体管
有了这个理论,后面要做的就不难了。(Bazinga!写到这里我已经彻底懵了,我是照着参考书写的。)
一个MOSFET就长这样。
<img src="https://i-blog.csdnimg.cn/blog_migrate/f530cde752dff0f2fc8f634aed0c16ac.png" data-rawwidth="357" data-rawheight="342" class="content_image" width="357">为了便于理解它的工作原理,我们可以把它简化成这样:
为了便于理解它的工作原理,我们可以把它简化成这样:
<img src="https://i-blog.csdnimg.cn/blog_migrate/1f92878db7cb9df16cc62677950ed72b.png" data-rawwidth="641" data-rawheight="473" class="origin_image zh-lightbox-thumb" width="641" data-original="https://pic2.zhimg.com/af795018c6c0530b8f771b34fb27584d_r.png">
当我们不给Gate这个电压的时候,我们得到了两个典型的PN Junction(Drain & Subtract, Subtract & Source),电流是无法流过的。
当我们给Gate施加一个正电压的时候,Gate的上层带正电,下层则带了负电。但因为Gate是个不导电的金属氧化物,所以它的下部会形成一个n type 通道(induced electron inversion layer)--电子可以直接从Source流到Drain。于是,我们得到了一个电流通路。
这就是我们的逻辑开关了。
最后,我们需要了解,MOSFET可以分为两种,一种叫P-MOS, 一种叫N-MOS。我们上面的图例其实是NMOS因为整个的载体为电子。很显然,PMOS的载体就是穴,它的source和drain都是P-type。
在现实的使用中,两者的区别就是:
High Gate Voltage Low Gate Voltage
PMOS 断路 通路
NMOS 通路 断路
<img src="https://i-blog.csdnimg.cn/blog_migrate/23d63d69ac3772a70514c5e5c595a58a.png" data-rawwidth="315" data-rawheight="167" class="content_image" width="315">
5.4. CMOS (Complementary MOSFET BALABALA)逻辑电路
单个的MOSFET似乎并没有神力,但当若干个mosfet组合到一起,我们就可以很轻松的得到各种我们想要的逻辑门。
<img src="https://i-blog.csdnimg.cn/blog_migrate/b8c59adecef2000eb35865175954d310.png" data-rawwidth="493" data-rawheight="420" class="origin_image zh-lightbox-thumb" width="493" data-original="https://pic1.zhimg.com/e388f0e4f51b59e9698a1b42a68c0100_r.png">
这个图例看起来很复杂,但其实是个纸老虎。首先,我们给Vdd通5V电源。
假设两个输入都是1, 即5V。对照5.3.的最后的表格
Q1: 通
Q2: 通
Q3: 断
Q4: 断 (Q1 和Q2 通导致Q5和Q6的Gate连到了5V,也即高电压上)
Q5: 通
Q6: 断
所以,输出连接到了Vdd,也即5V,也即1.
同理,其他易证。
确定要放弃本次机会?
福利倒计时
:
:
立减 ¥
普通VIP年卡可用
立即使用
Java潘老师
关注
关注
88
点赞
踩
247
收藏
觉得还不错?
一键收藏
知道了
15
评论
分享
复制链接
分享到 QQ
分享到新浪微博
扫一扫
举报
举报
专栏目录
15 条评论
您还未登录,请先
登录
后发表或查看评论
Java潘老师
博客等级
码龄11年
97
原创
604
点赞
1002
收藏
381
粉丝
关注
私信
热门文章
软件是如何驱动硬件的,代码是怎样对计算机实现控制的?
37934
bootstrap的treeview使用方法教程
36662
如何用java RSA生成生成公钥私钥(非对称加密)
33458
Windows下使用OpenSSL生成自签证书(亲测)
24668
classpath和classpath* 怎么理解?有什么区别
23103
分类专栏
项目源码
7篇
在线工具
1篇
笔记本电脑
9篇
大数据系列教程
17篇
Java
13篇
Spring
19篇
Hibernate
3篇
Struts
3篇
Maven
2篇
Hadoop
2篇
jQuery
1篇
WebService
2篇
BootStrap
1篇
数据库
7篇
前端
3篇
插件
6篇
底层原理
开发测试
2篇
tomcat
1篇
安全
2篇
Android
5篇
Linux
2篇
区块链
3篇
展开全部
收起
上一篇:
Hibernate插入Oracle数据库时间丢失时分秒问题解决
下一篇:
bootstrap的treeview使用方法教程
最新评论
获取Manus内测邀请码有哪些方法?
&上千个黎明:
邀请码过期了https://discord.gg/cD6CHU5y
svn没有绿色图标解决方案
huaihuai62:
其他有办法能解决吗
固态硬盘有缓存和没缓存有什么区别
james旸爷:
1.有缓存:好。
2.没缓存:不好,借用内存等做法相当于曲线救国。
Git常见的面试题
Java潘老师:
DevOps 和测试人员的 Git 面试问题看这里https://www.panziye.com/javainterview/8919.html
软件是如何驱动硬件的,代码是怎样对计算机实现控制的?
狗蛋儿fly:
没有后面了?正看的津津有味呢
大家在看
Prototypical Networks原理与PyTorch实现
574
还在手写SQL?Cursor+MCP让数据库对话式操作零门槛,小白也能玩转数据库!
Manacher算法——处理最长回文子串
330
洛谷B3650 [语言月赛202208] 求和
[论文阅读] 软件工程 | 需求工程中领域知识研究:系统映射与创新突破
654
最新文章
172 本编程语言学习入门电子书合集免费下载 | 优网资源
免费分享50本web全栈学习电子书
85本适合AI入门的人工智能书籍合集免费资源
2025年33篇
2024年10篇
2023年13篇
2022年2篇
2021年3篇
2020年20篇
2019年1篇
2018年14篇
2017年34篇
2016年16篇
目录
展开全部
收起