自制了一台计算机,可编程哦
接触计算机多年,经常会有一种云里雾里的感觉。今天,一起动手来自制一台计算机,加深体会和理解。
必须说明的是,计算机有复杂的,也有简单的,但结构和原理基本相通,本文制作的是最简单的计算机。
我也会对自制的简单计算机进行编程,体会编程的感觉,知道编程是怎么回事,理解计算机工作的原理。
一. 自制计算机的外形
在很长一段时间内,总是搞不清楚一些基本的概念和原理:比如什么是硬件? 硬件内部是怎样运行的?什么是软件?软件在哪里?软件究竟是怎样在硬件上跑起来的?硬件究竟是怎样执行软件的?
我将自制一台简单计算机,从电路的角度理解计算机的工作原理,给这台计算机编程,体会硬件和软件之间的相互作用。如下图是我制作的一台最原始的计算机,先来一睹它的外形,看看长啥样:
冯诺依曼结构 |
自制计算机 |
CPU运算器 |
U3加法器 |
CPU控制器 |
U1计数器 U4触发器 U5非门 时钟信号 |
存储器 |
U2存储器 |
输入设备 |
不涉及 (因为输入内容已提前存放于U2中) |
输出设备 |
数码管显示器 |
二. 自制计算机的构成
接下来,我们一起看看自制计算机的构成,从简单到复杂,我们一步一步地制作和讲解。
1. RS锁存器
来看RS锁存器电路,其特殊在于:U3的输出作为U2的输入,U4的输出作为U1的输入:
很容易分析出逻辑关系:
S |
R |
Q |
Q’ |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
保持 |
保持 |
1 |
1 |
0 |
0 |
有三点值得注意:
当S=0,R=0时,对或门没有任何贡献,所以不会对电路产生影响。此时,Q和Q'是相反的,必有一个为0,另一个为1.
当S=1,R=1时(这种输入并没有错),Q和Q'都为0,我们对这种情况并不感兴趣,所以可以忽略,故约定S和R不同时为1.
不考虑S=1,R=1这种输入组合时,Q和Q'总是相反的。
2. D锁存器
来看D锁存器电路。可用多个器件来确保RS锁存器两个输入端不能都为1,下图R和S输出端永远不可能同时为1:
来分析上图电路动图:
当E=0时,无论D怎么变, 经历R和S两个与门后,R和S的输出端总是0,所以Q和Q'总是保持原状。
当E=1时,经历R和S两个与门时,R和S输出端的值完全取决于D, 显然有Q=D.
可以看出:E是一个控制者,只有当E=1时,D的值才会保存到Q上。当E=0时,无论D怎么折腾,Q总是无动于衷。
3. D触发器
来看D触发器电路,它由两个D锁存器组成,构思非常巧妙,仅在上升沿触发时才有效:
来分析一下这个电路动图:
上下两个D锁存器的使能端是相反的,所以,无论控制开关E是0还是1,上下两个D锁存器必然有一个无效,导致不能把D数据保存到Q端。
当E从1变为0时,下面的D锁存器无效,因此也不能把D数据锁存到Q端。
当E从0变为1时,下面的D锁存器生效,上面的D锁存器无效,但U4的输出端之前已经获取了D端的数据,所以趁着下面的D锁存器的生效,把U4输出端的数据保存到Q端。因此,整体看来,当E从0变化到1时,能把D数据锁存到Q端。这种锁存,只在信号发生0到1的跳变瞬间,所以叫上升沿触发锁存。
可是,这个D触发器有点复杂,我们来抽象一下,直接使用封装好的D触发器,如下图,可以看到:当且仅当E从0变到1时,才把D保存到Q.
D触发器只能触发保存1位二进制,我们可以直接用封装好的74175芯片实现4位二进制的保存,如下图:
用开关提供上升沿,需要手动掰弄开关,非常麻烦。能不能搞一个自动上升沿呢?当然可以。
我们引入时钟信号,它不停地在0和1之间做变换,从而产生上升沿。时钟信号很简单,看动图:
想一下,为什么CPU需要时钟才能工作?这个问题很有趣,也很好回答,可以从两个方面来看:
计算机的理论模型是图灵机,而图灵机是有限状态机,需要有时钟信号驱动状态变化。
计算机中的数据需要按先后步骤进行保存和更新,以上述触发器为例,需要有上升沿信号来触发,所以需要时钟信号。
4. 计数器
利用D触发器,可以制作其他器件。如下动图中所示的计数器,遇到脉冲就计数:
时钟周期是1秒,每秒会有一个上升沿信号输入到U1的CLK端,于是U1的Q端就会每秒在0和1之间跳动一次,显然U1的Q'也是每秒在0和1之间跳动一次。
也就是说,对于U2的CLK而言,遇到一次上升沿需要2秒,因此U2的Q在0和1之间跳动1次需要2秒,看下表:
第n秒 |
U1 |
U2 |
U3 |
U4 |
U4U3U2U1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
2 |
0 |
1 |
0 |
0 |
2 |
3 |
1 |
1 |
0 |
0 |
3 |
4 |
0 |
0 |
1 |
0 |
4 |
5 |
1 |
0 |
1 |
0 |
5 |
6 |
0 |
1 |
1 |
0 |
6 |
7 |
1 |
1 |
1 |
0 |
7 |
8 |
0 |
0 |
0 |
1 |
8 |
9 |
1 |
0 |
0 |
1 |
9 |
10 |
0 |
1 |
0 |
1 |
A |
11 |
1 |
1 |
0 |
1 |
B |
12 |
0 |
0 |
1 |
1 |
C |
13 |
1 |
0 |
1 |
1 |
D |
14 |
0 |
1 |
1 |
1 |
E |
15 |
1 |
1 |
1 |
1 |
F |
一目了然,U1的Q变化最频繁,U2的Q变化不频繁,U3的Q变化更不频繁,U4的Q最懒惰。很显然,上述电路是一个计数器,从0到F, 一个一个地计数。
计数器很重要,若要不断地从存储中取出程序或数据,就得靠它了。所以,计数器被用作程序计数器,即Program Counter. 抽象封装好的计数器如下:
5. 完整计算机
到此为止,我们制作并使用了计数器、加法器、触发器、时钟信号、非门以及数码管显示器,把上述器件组装在一起,形成一台完整的计算机,如下所示:
这台简单计算机的电路图硬件都搭建好了,软件在哪里呢?软件就是程序,包括指令和数据。我们把软件程序存放在存储器U2中,其中存放的程序内容是:
000000000000000100000010000000110000010000000101
其功能是:计算1+2+3+4+5,这台计算机工作过程的动图如下,可以看到:1+2+3+4+5=FH=15
现在最大的疑问是:为什么上面那段程序表示1+2+3+4+5呢?计算机电路又是如何执行程序的呢?我们来仔细分析一下。
U2存储器中的程序是:
000000000000000100000010000000110000010000000101
这个程序不直观,为便于阅读,我们来分割一下:
可以看到,第一行是0,第二行是1,第三行是2,第四行是3,第五行是4,第六行是5. 存储器U2的输入端和输出端对应的关系如下:
U2输入端 A3A2A1A0 |
U2输出端 D3D2D1D0 其具体内容与我们写的程序有关 |
0000 |
0000 |
0001 |
0001 |
0010 |
0010 |
0011 |
0011 |
0100 |
0100 |
0101 |
0101 |
U2存储器左边的U1刚好是计数器,从0一直数到F,因此,当计数器数到3时,U2输入端刚好就是3,而U2此处存储的数据刚好是3.
我们对照上面的动图,整体理解一下计算机电路图的执行流程:
第1步:
开始,U1的输出值0,左边数码管显示0,U2输出值为0,U3加法器的输出值0,U4的输出值是0,右边数码管显示0.
第2步:
时钟信号经历上升沿,U1开始计数到1,U2输出值为1,左边数码管显示1,U3加法器的输出值还是1,但U4没有经历上升沿,故U4的输出值是0,右边数码管显示0.
第3步:
时钟信号经历下降沿,U1保持在1,U2输出值为1,左边数码管显示1,U3加法器的输出值还是1,U4刚好经历上升沿,故U4的输出值是1,右边数码管显示1.
还有很多步骤没有列出,我们把所有步骤放到表格中:
时钟信号 |
U1输出 |
U2输出 |
U3输出 |
U4输出
|
0 |
0 |
0 |
0 |
0 |
上升沿 |
1 |
1 |
1 |
0 |
下降沿 |
1 |
1 |
1 |
1 |
上升沿 |
2 |
2 |
3 |
1 |
下降沿 |
2 |
2 |
3 |
3 |
上升沿 |
3 |
3 |
6 |
3 |
下降沿 |
3 |
3 |
6 |
6 |
上升沿 |
4 |
4 |
A |
6 |
下降沿 |
4 |
4 |
A |
A |
上升沿 |
5 |
5 |
F |
A |
下降沿 |
5 |
5 |
F |
F |
对照电路图看表格,一目了然。可以看到,由于引入了U4触发器来保存数据,电路再也不会出现之前文章中遇到的死循环了。到此为止,我们的连续加法器终于实现了。
而且,这个连续加法器是自动的,这完全是因为有了时钟信号,它不断地制造上升沿,触发着计数器往前走,去存储器获取指令和数据,也触发着把U3加法器输出端的值安全地保存到U4的输出端,让它再次输入到U3参与计算。
如果没有时钟信号,我们还要去一个开关一个开关地掰弄,去构造上升沿来控制电路。我在仿真时,时钟信号频率是1Hz,也就是周期是1秒,信号为0的时间占0.5秒,信号为1的时间占0.5秒,1秒之内有1个上升沿和一个下降沿。
我把时钟的频率调快到10Hz,发现连续加法的计算时间也变快了10倍,这是因为:时钟信号的频率快了,上升沿的次数就更频繁了,自然能更快地迫使其他器件上的值进行变化。
我电脑的主频是3.6GHz,这就是时钟频率,它每秒产生几十亿次上升沿/下降沿信息,迫使着其他器件快速变化。一般来说,主频越大,CPU的运算速度就越快,道理显而易见。
6. 硬件与软件
电路是硬件,存储在U2中的信息是软件。我们买到手机后,基本不会对硬件进行变化,但经常安装或者卸载其中的软件,而正是不同的软件,使得手机有不同的功能。
在不改变上述电路硬件的情况下,我们可在U2中装入不同的软件,从而实现不同的功能。比如,我们写一个新程序:
00000000000000100000010000001000
把程序塞到U2存储器中,重新让电路通电。从如下动图中显而易见,这是在计算2+4+8=EH=14,由此可见:不同的软件程序,实现了不同的功能。
三. 自制计算机的编程
用0和1写出来的程序,叫机器语言程序,直接在硬件上运行,比起掰弄电路开关,已经有很大进步。但是,如果一直用0和1来写程序,还不能出现一点点差错,谁受得了呢?
一大串的0和1,太难懂了,它是机器世界的语言,而人又有人的语言,这两种语言是不相通的,因此,我们需要探索出更好的编写程序的方法,让人更轻松点。怎么办?
我们回头看1+2+3+4+5的机器语言:
000000000000000100000010000000110000010000000101
怎么降低人编写程序的难度呢?我们可以考虑这么写:
ORG 0000H
DB 00H
DB 01H
DB 02H
DB 03H
DB 04H
DB 05H
END
这种语言叫汇编语言,看起来舒服多了。现在的问题是,需要一个工具把汇编语言转化为机器语言,这个转换的工具就叫汇编器,如下图:
现在编程就简单多了:先用汇编语言写程序,然后用汇编器这个工具,把汇编语言程序转化为机器语言程序。
如果要计算2+4+8,我们再也不用与0和1这种折磨人的机器语言打交道了,直接用汇编语言写汇编程序,如下:
ORG 0000H
DB 00H
DB 02H
DB 04H
DB 08H
END
经汇编器工具转换后,上述的汇编语言程序变为了机器语言程序,而这正是硬件电路所需要的语言,具体如下:
00000000000000100000010000001000
然后,我们自制的计算机执行这段机器语言程序,得到的结果是14. 可是,用汇编语言还是憋屈,不好理解,不近人情。
于是,需要再次抽象,越抽象越接近事物的本质,为了降低编程难度,我们再次优化编程方法,采用高级语言,如下:
int a=1+2+3+4+5;
printf("%d", a);
然而,电路毕竟不认识高级语言,只认识高低电平,即1和0,所以,也需要工具来对高级语言进行转换,关系如下所示:
我们从如下表格中,可以看到机器语言、汇编语言以及高级语言的对比。显然,用高级语言编程更容易,更加直观:
目的 |
机器语言 |
汇编语言 |
高级语言 |
计算 1+2+3+4+5 |
000000000000000100000010000000110000010000000101 |
ORG 0000H DB 00H DB 01H DB 02H DB 03H DB 04H DB 05H END |
int a=1+2+3+4+5; printf("%d", a); |
计算 2+4+8 |
00000000000000100000010000001000 |
ORG 0000H DB 00H DB 02H DB 04H DB 08H END |
int a=2+4+8; printf("%d", a); |
这里有两点补充说明:
上述的汇编语言很简单,不涉及到指令,只涉及到数据存放的位置。有一些朋友可能觉得上述汇编语言的指令是伪指令,但没有关系,我们依然把它当汇编语言理解,并无副作用。而且经汇编器转换后,生成的机器代码,确实可以在我们制作的计算机上运行。
上述的高级语言,经通用的编译器和汇编器转换得到的机器语言程序,没法在我们自制的计算机上运行,必须经过特定的编译器才可以,我们无需对这种特殊的编译器做进一步了解,毕竟编译器只是个转换工具。
我们已经从原始的掰弄开关来控制电路,上升到利用机器语言0和1来控制电路,然后上升到用汇编语言来控制电路,最后上升到利用高级语言来控制电路。
逐步地,我们从纷繁复杂的电路细节中解脱出来,这是一个不断进行抽象、不断远离具体细节、不断接近事物本质的过程,从此,也站在更高的维度上了。
好的,到此为止,本文也将告一段落。对于想搞懂计算机原理的朋友而言,如果能亲自动手完成本文的实验,那么肯定会加深对计算机原理的理解,加油!
自制了一台计算机,可编程哦相关推荐
- 如何制造一台计算机,编程多年后我开始思考这个问题
周末,我高中的弟弟问我这样一个问题:"为什么电脑都是从 C 盘开始?A 盘.B 盘哪去了?" 平时他总是问我一些奇怪的问题,其实这是个暴露年龄的问题,作为零五后,他不知道,我不怪他 ...
- 制作一台计算机需要多少知识,如何制造一台计算机,编程多年后我开始思考这个问题...
周末,我高中的弟弟问我这样一个问题:"为什么电脑都是从 C 盘开始?A 盘.B 盘哪去了?" 平时他总是问我一些奇怪的问题,其实这是个暴露年龄的问题,作为零五后,他不知道,我不怪他 ...
- 祖思机——第一台二进制可编程计算机
巴贝奇领先全人类一个世纪提出了可编程机械计算机的设想,但最终没能将其转换为现实--分析机的建造甚至迄今都没有人能完成.历史翘首期盼了百年,却在纳粹德国见证了第一台可编程计算机的诞生. 它的发明者--康 ...
- 10万多台计算机瘫痪,微信勒索病毒的背后竟是最不起眼的易语言
近日东莞警方破获了一起微信支付勒索病毒案,病毒研发制作者利用自制的病毒,入侵用户的计算机,非法获取淘宝.支付宝.百度网盘等各类用户账号,并感染了全网10万余台计算机.嫌疑人罗某某还通过执行命令,对感染 ...
- 清华贵系的期末大作业:奋战三周,造台计算机!
大数据文摘授权转载自AI科技评论 作者 | 蒋宝尚 编辑丨陈彩娴 本科大三,正在学习计算机组成原理,能做个什么项目? 清华大学贵系说:造台计算机吧! 清华有门本科三年级必修课,名为<计算机组成原 ...
- 美国研发出第一台计算机的时间,研发世界第一台电脑的核心人物,被美国隐藏35年,只因他是个华人...
电脑在如今已经十分常见,不管是生活中查阅资料也好,又或者是工作也好.都是一些人不可缺少的一种工具,形成了规模巨大的计算机产业,对人类的生产活动和社会活动产生了极其重要的影响.目前来说,计算机处在一个相 ...
- 人工智能秘史(二):美国第一台计算机背后的女程序员
相关文章:人工智能秘史(一):会下棋的土耳其机器人 1946年2月14日,记者纷纷聚集到宾夕法尼亚大学摩尔工程学院(Moore School of Engineering),准备见证全世界最早的通用电 ...
- 计算机英语(编程词汇大全)
计算机英语(编程词汇大全) 来源地址:https://blog.csdn.net/D_hj05/article/details/80274471 application [ˌæplɪ'keɪʃ(ə)n ...
- 耗时2天,我自制了一台体感游戏机
大家好,欢迎来到 Crossin的编程教室~ 几天不见,Crossin 又去做什么游戏去了呢?这次我做的不是游戏,而是游戏机!而且是体感游戏机. 说到体感游戏,现在大家可能最多想到的是 switch ...
最新文章
- html js文本框文字列出,js实现文本框中输入文字页面中div层同步获取文本框内容的方法...
- CVPR2021:推广到开放世界的在线自适应深度视觉里程计
- 压缩感知的阶段性总结
- iOS面试用到的知识点和技术点--第二章
- 螺旋天线有方向性吗_螺旋天线方向图
- PHP 实现Session入库/存入redis
- c语言大作业万年历,C语言实现简单万年历
- centos6 和 centos7 防火墙基本操作
- 【SBUS,串口DMA】用STM32F407的串口DMA读取SBUS接收机信号
- java进制转换所有方法_Java进制转换方法整理
- 笔记本开机密码忘记了怎么解决,消除笔记本密码
- c语言hook函数,另类iOS上的C函数hook
- 利用GAN来为冷启动用户生成 行为特征完成yelp数据集上,冷启动垃圾识别的问题。
- 阿里云服务器CentOS搭建
- 贝塞尔波纹+蒙版和螺旋线进度条控件
- 谁的php最厉害,羽坛四大天王谁最强?羽毛球四大天王排行榜(图)
- 百度地图TextureMapView变黑
- 如何优雅地下载b站视频
- 电子通信计算机专业的英语论文,电子信息工程英文参考文献
- docker containerd.io、docker-ce、docker-ce-cli的区别(docker版本安装docker安装方法)(Docker CE和Docker EE,docker.io)
热门文章
- Affymetrix公司芯片类型和对应平台
- 留学生如何利用好ChatGPT提高学习效率?
- 算法竞赛从入门到进阶pdf_好书送不停 | 算法竞赛入门到进阶
- PS 基础知识 .pat文件如何使用
- 微信小程序web-view的{errMsg: “invokeMiniProgramAPI:ok“}报错解决方案
- java 回头是岸总结入门篇(二)meavn
- webservice-CXF3.0
- 从键盘录入一个字符串,统计该串中有大写字母、小写字母、数字各有多少个。比如:Hello12345World大写:2个 小写:8个数字:5个。
- Ubuntu无法打开wifi的解决方法
- 0-1000随机自然数生成