完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一. “冯诺依曼结构”简介
程序员每天做的事情,就是不停地给计算机喂食,喂的是0和1组成的串。如下是我们的第一个程序,体会下编程的感觉: 000000000000000100000010000000110000010000000101 这是机器语言程序,具体功能是计算1+2+3+4+5,这个程序可以运行在我们本文自制的简单计算机上,其中0和1所在的位置,不能出错。既然程序需要运行在硬件电路上,所以我们得关注硬件电路,还是从冯诺依曼说起吧。 冯诺依曼,被称为现代计算机之父,关于他的生平,一篇文章讲不完,故直接省略。只说一句:1903年,冯诺依曼出生在匈牙利的布达佩斯,就是在这里,刘诗雯今年首次获得了世乒赛单打冠军,十年磨一剑,真的不容易。 冯诺依曼设计了一种计算机结构---“冯诺依曼结构”,它是现代计算机的基础, 其最基本的原理是:程序存储。 简单看下现代计算机的组成,其中红色的五个部分就是“冯诺依曼结构”的五大部件: 在很长一段时间内,总是搞不清楚一些基本的概念和原理, 比如什么是硬件? 硬件内部是怎样运行的?什么是软件?软件在哪里?软件究竟是怎样在硬件上跑起来的?硬件究竟是怎样执行软件的?本文会逐一给出答案。 在本文中,我们将用proteus仿真一台简单计算机,从电路的角度理解计算机的工作原理,并给这台计算机编写程序,体会编程的感觉,体会硬件和软件之间的相互作用。 先来看前面文章留下来的问题:自动连续加法器的实现。当时的尝试都失败了,原因是:缺少合适的器件,导致电路死循环。失败的电路图如下(gif帧率是1桢/秒,所以感觉变化不快,但实际很快): 为了解决自动连续加法的问题,我们用proteus制作了一台最原始的计算机,其功能单一,先来一睹芳容: 这就是一台自制的简单计算机,其组成部件和“冯诺依曼结构”基本对应,如下表所示:
二. 自制简易计算机及机器语言编程 首先看如下电路, 其特殊之处在于:U3的输出作为U2的输入,U4的输出作为U1的输入。真不知道是谁没事干,去尝试这样连接电路。但从结果来看,是挺有意思的: 很容易分析出下表逻辑关系:
a. 当S=0,R=0时,对或门没有任何贡献,所以不会对电路产生影响。此时,Q和Q'是相反的关系,必有一个为0,另一个为1. b. 当S=1,R=1时(这种输入并没有错),Q和Q'都为0,我们对这种情况不感兴趣,所以可以忽略它,故约定S和R不能同时为1。有很多书总是说:S=1,R=1是非法输入,这真是搞笑啊,是不符合要求的输入还是违法的输入?都不是。 c. 不考虑S=1,R=1这种输入组合时,Q和Q'总是相反的。 上图这个电路,叫RS锁存器。注意,有的书上并不区分锁存器和触发器这两个概念,其实,准确地讲:电平触发的叫锁存器(latch),上升沿/下降沿触发的叫触发器(flipflop)。 根据约定,RS锁存器的两个输入端不能都为1,我们完全可以多加几个器件来达到这个控制目的,下图中R和S输出端的值永远不可能同时为1: 来分析上图中的电路: a. 当E=0时,无论D怎么变, 经历R和S两个与门后,R和S的输出端总是0, 所以Q和Q'总是保持原状。 b. 当E=1时,经历R和S两个与门时,R和S输出端的值完全取决于D, 显然有Q=D. 可以看出:E是一个控制者的角色,只有当E=1时,D的值才会保存到Q上。而当E=0时, 无论D怎么折腾,Q总是无动于衷。E是老大,官大一级压死人。所以,把E叫使能端, 把D叫数据端。 上图这个电路,叫D锁存器,仅在E端允许时,完成锁存。 继续来看一个更有趣的电路,把两个D锁存器串在一起, 如下图: 来分析一下这个电路: a. 上下两个D锁存器的使能端是相反的,所以,无论控制开关E是0还是1, 上下两个D锁存器必然有一个无效,导致不能把D数据保存到Q端。 b. 当E从1变为0时,下面的D锁存器无效,因此也不能把D数据锁存到Q端。 c. 当E从0变为1时,下面的D锁存器生效,上面的D锁存器无效,但U4的输出端之前已经获取了D端的数据, 所以趁着下面的D锁存器的生效,把U4输出端的数据保存到Q端。因此,整体看来,当E从0变化到1时,能把D数据锁存到Q端。这种锁存,只在信号发生0到1的跳变瞬间,所以叫上升沿触发锁存。 上图中的电路,叫D触发器,仅在上升沿触发时有效。 可是,这个D触发器有点复杂,我们来抽象一下,直接使用封装好的D触发器,如下图,可以看到:当且仅当E从0变到1时,才把D保存到Q。 用E开关提供上升沿,需要手动掰弄开关,非常麻烦。能不能搞一个自动上升沿呢?当然可以。我们引入时钟信号,它不停地在0和1之间做变换,从而产生上升沿。时钟信号很简单,直接看图: 曾经在知乎上看到这样一个问题:为什么CPU需要时钟才能工作? 这个问题很好回答, 从两个方面来看: a. 计算机的理论模型是图灵机,而图灵机是有限状态机,需要有时钟信号驱动状态变化。 b. 计算机中的数据需要按先后步骤进行保存和更新,以上述触发器为例,需要有上升沿信号来触发,所以需要时钟信号。 D触发器只能触发保存1位二进制,我们可以直接用封装好的74175芯片实现4位二进制的保存,如下图: 利用D触发器,可以制作其他器件,比如下图中所示的计数器: 这个电路图很好分析。时钟周期是1秒,也就是说,每秒会有一个上升沿信号输入到U1的CLK端,于是U1的Q端就会每秒在0和1之间跳动一次,显然U1的Q'也是每秒在0和1之间跳动一次。也就是说,对于U2的CLK而言,遇到一次上升沿需要2秒,因此U2的Q在0和1之间跳动1次需要2秒,看下表:
现在对上述自制的计数器进行抽象,直接使用封装好的计数器,静图如下: 计数器很重要,若要不断地从存储中取出程序或数据,就得靠它了。所以,很多时候,计数器被用作程序计数器,即Program Counter. 好的,到此为止,我们制作并使用过计数器、加法器、触发器、时钟信号、非门以及数码管显示器,但还剩下存储器没有制作出来,不要着急,制作存储器是我们后续文章要专门讲述的内容,暂时先直接使用存储器。 把上述器件组装在一起,形成一台完整的计算机,如下图所示: 这台简单计算机的电路图硬件都搭建好了, 软件在哪里呢?软件就是程序,包括指令和数据。我们把软件程序存放在存储器U2中,其中存放的程序内容是: 000000000000000100000010000000110000010000000101 其功能是:计算1+2+3+4+5 这台计算机工作过程的动图如下(感觉动图中的器件很模糊,大家可以对照上面的静图一起看): 可以看到:1+2+3+4+5=FH=15 现在最大的疑问是:为什么上面那段程序表示1+2+3+4+5呢?计算机电路又是如何执行程序的呢?我们来仔细分析一下。 U2存储器中的程序是: 000000000000000100000010000000110000010000000101 这个程序不直观,为便于阅读,我们来分割一下: 000000000000000100000010000000110000010000000101 可以看到,第一行是0, 第二行是1, 第三行是2, 第四行是3, 第五行是4, 第六行是5. 存储器U2的输入端和输出端对应的关系如下(注意:由于我们计算的数值不大,所以不需要用到A7A6A5A4和D7D6D5D4):
我们对照上面的动图,整体理解一下计算机电路图的执行流程: 第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. 还有很多步骤没有列出,我们把所有步骤放到表格中:
而且,这个连续加法器是自动的,这完全是因为有了时钟信号,它不断地制造上升沿,触发着计数器往前走,去存储器获取程序(指令和数据),也触发着把U3加法器输出端的值安全地保存到U4的输出端,让它再次输入到U3参与计算。如果没有时钟信号,我们还要去一个开关一个开关地掰弄,去构造上升沿来控制电路。烦就一个字,我只说一次。 在进行proteus仿真时,时钟信号的频率是1Hz, 也就是周期是1秒,信号为0的时间占0.5秒, 信号为1的时间占0.5秒, 1秒之内有1个上升沿和一个下降沿。我把时钟的频率调快到10Hz,发现连续加法的计算时间也变快了10倍,这是因为:时钟信号的频率快了,上升沿的次数就更频繁了,自然能更快地迫使其他器件上的值进行变化。 我们来看如下的Intel CPU芯片,其主频是3.6GHz,这就是它的时钟频率,它每秒产生几十亿次上升沿/下降沿信息,迫使着其他器件快速变化。一般来说,在其他指标一样时,主频越大,计算机CPU的运算速度就越快,应该很容易理解这一点。 电路是硬件,存储在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. 可是,用汇编语言还是憋屈,不好理解,不近人情。于是乎,我们需要再次抽象,越抽象越接近事物的本质,而我们的本质诉求是计算加法。为了降低编程难度,我们再次优化编程方法,采用高级语言(如C/C++语言、Java语言等)来编写程序,如下: int a=1+2+3+4+5;printf("%d", a); 这样就更加清晰了。然而,电路毕竟不认识这些高级语言,电路只认识高低电平,即1和0, 所以,也需要工具来对高级语言进行转换,如下图: 我们从如下表格来看机器语言、汇编语言以及高级语言的对比。显然,用高级语言编程更容易更直观:
a. 上述的汇编语言很简单,不涉及到指令,只涉及到数据存放的位置。有一些朋友可能觉得上述汇编语言的指令是伪指令,但没有关系,我们依然把它当汇编语言理解,并无副作用。而且经汇编器转换后,生成的机器代码,确实可以在我们制作的计算机上运行。 b. 上述的高级语言,经通用的编译器和汇编器转换得到的机器语言程序,没法在我们自制的计算机上运行,必须经过特定的编译器才可以,我们无需对这种特殊的编译器做进一步了解,毕竟编译器只是个转换工具。 我们已经从原始的掰弄开关来控制电路,上升到利用机器语言0和1来控制电路,然后上升到用汇编语言来控制电路,最后上升到利用高级语言来控制电路。一步一步地,我们从纷繁复杂的电路细节中解脱出来了,这是一个不断进行抽象、不断远离具体细节、不断接近事物本质的过程,从此,也站在更高的维度上看待和处理问题。就像公司的老板一样,不需要管太多底层的繁琐细节,只需要关注高层次的本质问题。 本文快要接近尾声了, 我们来总结一下本文内容: 首先,介绍了“冯诺依曼结构”计算机的大致组成,并总是想着体验一下编程的感觉。 其次,为了构建一台计算机,我们一步一步地制作器件,包括RS锁存器、D锁存器、D触发器、4位D触发器、计数器和时钟信号, 并组装成了一台完整的计算机,然后编写了机器语言程序,从掰弄开关的物理底层操作中解脱出来,初步体会到了机器语言编程的感觉。 最后,为了让人更轻易地编程,提升编程的效率,把人真正从底层的繁琐细节中解脱出来,我们介绍了汇编语言和高级语言,并终于体会到了各层语言编程的感觉。 还剩一个问题,本文使用了存储器ROM, 而且没有做详细介绍,实际上,ROM是只读存储器(Read Only Memory), 其中的内容一旦固定后,就不太容易更改。存储器是非常重要的,尤其是在每天产生海量数据的现代社会。在后续文章中,我们会对存储器相关的内容做更多的介绍。 |
|||||
|
|||||
只有小组成员才能发言,加入小组>>
4508个成员聚集在这个小组
加入小组3334 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4262 浏览 1 评论
4289 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 15:58 , Processed in 0.627249 second(s), Total 75, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号