接触计算机多年,经常会有一种云里雾里的感觉。今天,一起动手来自制一台计算机,加深体会和理解。

必须说明的是,计算机有复杂的,也有简单的,但结构和原理基本相通,本文制作的是最简单的计算机。

我也会对自制的简单计算机进行编程,体会编程的感觉,知道编程是怎么回事,理解计算机工作的原理。

一. 自制计算机的外形

在很长一段时间内,总是搞不清楚一些基本的概念和原理:比如什么是硬件? 硬件内部是怎样运行的?什么是软件?软件在哪里?软件究竟是怎样在硬件上跑起来的?硬件究竟是怎样执行软件的?

我将自制一台简单计算机,从电路的角度理解计算机的工作原理,给这台计算机编程,体会硬件和软件之间的相互作用。如下图是我制作的一台最原始的计算机,先来一睹它的外形,看看长啥样:

冯诺依曼结构

自制计算机

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 0000HDB 00HDB 01HDB 02HDB 03HDB 04HDB 05HEND

这种语言叫汇编语言,看起来舒服多了。现在的问题是,需要一个工具把汇编语言转化为机器语言,这个转换的工具就叫汇编器,如下图:

现在编程就简单多了:先用汇编语言写程序,然后用汇编器这个工具,把汇编语言程序转化为机器语言程序。

如果要计算2+4+8,我们再也不用与0和1这种折磨人的机器语言打交道了,直接用汇编语言写汇编程序,如下:​​​​​​​

ORG 0000HDB 00HDB 02HDB 04HDB 08HEND

经汇编器工具转换后,上述的汇编语言程序变为了机器语言程序,而这正是硬件电路所需要的语言,具体如下:

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来控制电路,然后上升到用汇编语言来控制电路,最后上升到利用高级语言来控制电路。

逐步地,我们从纷繁复杂的电路细节中解脱出来,这是一个不断进行抽象、不断远离具体细节、不断接近事物本质的过程,从此,也站在更高的维度上了。

好的,到此为止,本文也将告一段落。对于想搞懂计算机原理的朋友而言,如果能亲自动手完成本文的实验,那么肯定会加深对计算机原理的理解,加油!

自制了一台计算机,可编程哦相关推荐

  1. 如何制造一台计算机,编程多年后我开始思考这个问题

    周末,我高中的弟弟问我这样一个问题:"为什么电脑都是从 C 盘开始?A 盘.B 盘哪去了?" 平时他总是问我一些奇怪的问题,其实这是个暴露年龄的问题,作为零五后,他不知道,我不怪他 ...

  2. 制作一台计算机需要多少知识,如何制造一台计算机,编程多年后我开始思考这个问题...

    周末,我高中的弟弟问我这样一个问题:"为什么电脑都是从 C 盘开始?A 盘.B 盘哪去了?" 平时他总是问我一些奇怪的问题,其实这是个暴露年龄的问题,作为零五后,他不知道,我不怪他 ...

  3. 祖思机——第一台二进制可编程计算机

    巴贝奇领先全人类一个世纪提出了可编程机械计算机的设想,但最终没能将其转换为现实--分析机的建造甚至迄今都没有人能完成.历史翘首期盼了百年,却在纳粹德国见证了第一台可编程计算机的诞生. 它的发明者--康 ...

  4. 10万多台计算机瘫痪,微信勒索病毒的背后竟是最不起眼的易语言

    近日东莞警方破获了一起微信支付勒索病毒案,病毒研发制作者利用自制的病毒,入侵用户的计算机,非法获取淘宝.支付宝.百度网盘等各类用户账号,并感染了全网10万余台计算机.嫌疑人罗某某还通过执行命令,对感染 ...

  5. 清华贵系的期末大作业:奋战三周,造台计算机!

    大数据文摘授权转载自AI科技评论 作者 | 蒋宝尚 编辑丨陈彩娴 本科大三,正在学习计算机组成原理,能做个什么项目? 清华大学贵系说:造台计算机吧! 清华有门本科三年级必修课,名为<计算机组成原 ...

  6. 美国研发出第一台计算机的时间,研发世界第一台电脑的核心人物,被美国隐藏35年,只因他是个华人...

    电脑在如今已经十分常见,不管是生活中查阅资料也好,又或者是工作也好.都是一些人不可缺少的一种工具,形成了规模巨大的计算机产业,对人类的生产活动和社会活动产生了极其重要的影响.目前来说,计算机处在一个相 ...

  7. 人工智能秘史(二):美国第一台计算机背后的女程序员

    相关文章:人工智能秘史(一):会下棋的土耳其机器人 1946年2月14日,记者纷纷聚集到宾夕法尼亚大学摩尔工程学院(Moore School of Engineering),准备见证全世界最早的通用电 ...

  8. 计算机英语(编程词汇大全)

    计算机英语(编程词汇大全) 来源地址:https://blog.csdn.net/D_hj05/article/details/80274471 application [ˌæplɪ'keɪʃ(ə)n ...

  9. 耗时2天,我自制了一台体感游戏机

    大家好,欢迎来到 Crossin的编程教室~ 几天不见,Crossin 又去做什么游戏去了呢?这次我做的不是游戏,而是游戏机!而且是体感游戏机. 说到体感游戏,现在大家可能最多想到的是 switch ...

最新文章

  1. html js文本框文字列出,js实现文本框中输入文字页面中div层同步获取文本框内容的方法...
  2. CVPR2021:推广到开放世界的在线自适应深度视觉里程计
  3. 压缩感知的阶段性总结
  4. iOS面试用到的知识点和技术点--第二章
  5. 螺旋天线有方向性吗_螺旋天线方向图
  6. PHP 实现Session入库/存入redis
  7. c语言大作业万年历,C语言实现简单万年历
  8. centos6 和 centos7 防火墙基本操作
  9. 【SBUS,串口DMA】用STM32F407的串口DMA读取SBUS接收机信号
  10. java进制转换所有方法_Java进制转换方法整理
  11. 笔记本开机密码忘记了怎么解决,消除笔记本密码
  12. c语言hook函数,另类iOS上的C函数hook
  13. 利用GAN来为冷启动用户生成 行为特征完成yelp数据集上,冷启动垃圾识别的问题。
  14. 阿里云服务器CentOS搭建
  15. 贝塞尔波纹+蒙版和螺旋线进度条控件
  16. 谁的php最厉害,羽坛四大天王谁最强?羽毛球四大天王排行榜(图)
  17. 百度地图TextureMapView变黑
  18. 如何优雅地下载b站视频
  19. 电子通信计算机专业的英语论文,电子信息工程英文参考文献
  20. docker containerd.io、docker-ce、docker-ce-cli的区别(docker版本安装docker安装方法)(Docker CE和Docker EE,docker.io)

热门文章

  1. Affymetrix公司芯片类型和对应平台
  2. 留学生如何利用好ChatGPT提高学习效率?
  3. 算法竞赛从入门到进阶pdf_好书送不停 | 算法竞赛入门到进阶
  4. PS 基础知识 .pat文件如何使用
  5. 微信小程序web-view的{errMsg: “invokeMiniProgramAPI:ok“}报错解决方案
  6. java 回头是岸总结入门篇(二)meavn
  7. webservice-CXF3.0
  8. 从键盘录入一个字符串,统计该串中有大写字母、小写字母、数字各有多少个。比如:Hello12345World大写:2个 小写:8个数字:5个。
  9. Ubuntu无法打开wifi的解决方法
  10. 0-1000随机自然数生成