文中大部分内容来自《CODE》,一本生动介绍计算机原理的书籍,非科班出身的可以看看了解一下计算机基础。


首先要开始这个话题要先说一下半导体。啥叫半导体?

半导体其实就是介于导体和绝缘体中间的一种东西,比如二极管。

电流可以从A端流向C端,但反过来则不行。你可以把它理解成一种防止电流逆流的东西。

当C端10V,A端0V,二极管可以视为断开。

当C端0V,A端10V,二极管可以视为导线,结果就是A端的电流源源不断的流向C端,导致最后的结果就是A端=C端=10V

等等,不是说好的C端0V,A端10V么?咋就变成结果是A端=C端=10V了?

你可以把这个理解成初始状态,当最后稳定下来之后就会变成A端=C端=10V。

文科的童鞋们对不住了,实在不懂问高中物理老师吧。反正你不能理解的话就记住这种情况下它相当于导线就行了。

利用半导体,我们可以制作一些有趣的电路,比如【与门】

此时A端B端只要有一个是0V,那Y端就会和0V地方直接导通,导致Y端也变成0V。只有AB两端都是10V,Y和AB之间才没有电流流动,Y端也才是10V。

我们把这个装置成为【与门】,把有电压的地方计为1,0电压的地方计为0。至于具体几V电压,那不重要。

也就是AB必须同时输入1,输出端Y才是1;AB有一个是0,输出端Y就是0。

其他还有【或门】【非门】和【异或门】,跟这个都差不多,或门就是输入有一个是1输出就是1,输入00则输入0。

非门也好理解,就是输入1输出0,输入0输出1。

异或门难理解一些,不过也就那么回事,输入01或者10则输出1,输入00或者11则输出0。(即输入两个一样的值则输出0,输入两个不一样的值则输出1)。

这几种门都可以用二极管做出来,具体怎么做就不演示了,有兴趣的童鞋可以自己试试。每次都画二极管也是个麻烦,我们就把门电路简化成下面几个符号。

然后我们就可以用门电路来做CPU了。当然做CPU还是挺难的,我们先从简单的开始:加法器。

加法器顾名思义,就是一种用来算加法的电路,最简单的就是下面这种。

AB只能输入0或者1,也就是这个加法器能算0+0,1+0或者1+1。

输出端S是结果,而C则代表是不是发生进位了,二进制1+1=10嘛。这个时候C=1,S=0

费了大半天的力气,算个1+1是不是特别有成就感?

那再进一步算个1+2吧(二进制01+10),然后我们就发现了一个新的问题:第二位需要处理第一位有可能进位的问题,所以我们还得设计一个全加法器。

每次都这么画实在太麻烦了,我们简化一下

也就是有3个输入2个输出,分别输入要相加的两个数和上一位的进位,然后输入结果和是否进位。

然后我们把这个全加法器串起来

我们就有了一个4位加法器,可以计算4位数的加法也就是15+15,已经达到了幼儿园中班水平,是不是特别给力?

做完加法器我们再做个乘法器吧,当然乘任意10进制数是有点麻烦的,我们先做个乘2的吧。

乘2就很简单了,对于一个2进制数数我们在后面加个0就算是乘2了

比如:

5=101(2)10=1010(2)

所以我们只要把输入都往前移动一位,再在最低位上补个零就算是乘2了。具体逻辑电路图我就不画,你们知道咋回事就行了。

那乘3呢?简单,先位移一次(乘2)再加一次。乘5呢?先位移两次(乘4)再加一次。

所以一般简单的CPU是没有乘法的,而乘法则是通过位移和加算的组合来通过软件来实现的。这说的有点远了,我们还是继续做CPU吧。

现在假设你有8位加法器了,也有一个位移1位的模块了。串起来你就能算了!

(A+B)X2

激动人心,已经差不多到了准小学生水平。

那我要是想算呢?

AX2+B

简单,你把加法器模块和位移模块的接线改一下就行了,改成输入A先过位移模块,再进加法器就可以了。

啥????你说啥???你的意思是我改个程序还得重新接线?

所以你以为呢?编程就是把线来回插啊。

惊喜不惊喜?意外不意外?

早期的计算机就是这样编程的,几分钟就算完了但插线好几天。而且插线是个细致且需要耐心的工作,所以那个时候的程序员都是清一色的漂亮女孩子,穿制服的那种,就像照片上这样。是不是有种生不逢时的感觉?

虽然和美女作伴是个快乐的事,但插线也是个累死人的工作。所以我们需要改进一下,让CPU可以根据指令来相加或者乘2。

这里再引入两个模块,一个叫flip-flop,简称FF,中文好像叫触发器。

这个模块的作用是存储1bit数据。比如上面这个RS型的FF,R是Reset,输入1则清零。S是Set,输入1则保存1。RS都输入0的时候,会一直输出刚才保存的内容。

我们用FF来保存计算的中间数据(也可以是中间状态或者别的什么),1bit肯定是不够的,不过我们可以并联嘛,用4个或者8个来保存4位或者8位数据。这种我们称之为寄存器(Register)。

另外一个叫MUX,中文叫选择器。

这个就简单了,sel输入0则输出i0的数据,i0是什么就输出什么,01皆可。同理sel如果输入1则输出i1的数据。当然选择器可以做的很长,比如这种四进一出的

具体原理不细说了,其实看看逻辑图琢磨一下就懂了,知道有这个东西就行了。

有这个东西我们就可以给加法器和乘2模块(位移)设计一个激活针脚。

这个激活针脚输入1则激活这个模块,输入0则不激活。这样我们就可以控制数据是流入加法器还是位移模块了。

于是我们给CPU先设计8个输入针脚,4位指令,4位数据。

我们再设计3个指令:

0100,数据读入寄存器0001,数据与寄存器相加,结果保存到寄存器0010,寄存器数据向左位移一位(乘2)

为什么这么设计呢,刚才也说了,我们可以为每个模块设计一个激活针脚。然后我们可以分别用指令输入的第二第三第四个针脚连接寄存器,加法器和位移器的激活针脚。

这样我们输入0100这个指令的时候,寄存器输入被激活,其他模块都是0没有激活,数据就存入寄存器了。同理,如果我们输入0001这个指令,则加法器开始工作,我们就可以执行相加这个操作了。

这里就可以简单回答这个问题的第一个小问题了:

那cpu 是为什么能看懂这些二级制的数呢?

为什么CPU能看懂,因为CPU里面的线就是这么接的呗。你输入一个二进制数,就像开关一样激活CPU里面若干个指定的模块以及改变这些模块的连同方式,最终得出结果。

几个可能会被问道的问题

Q:CPU里面可能有成千上万个小模块,一个32位/64位的指令能控制那么多吗?

A:我们举例子的CPU里面只有3个模块,就直接接了。真正的CPU里会有一个解码器(decoder),把指令翻译成需要的形式。

Q:你举例子的简单CPU,如果我输入指令0011会怎么样?

A:当然是同时激活了加法器和位移器从而产生不可预料的后果,简单的说因为你使用了没有设计的指令,所以后果自负呗。(在真正的CPU上这么干大概率就是崩溃呗,当然肯定会有各种保护性的设计,死也就死当前进程)

细心的小伙伴可能发现一个问题:你设计的指令

【0001,数据与寄存器相加,结果保存到寄存器】

这个一步做不出来吧?毕竟还有一个回写的过程,实际上确实是这样。我们设计的简易CPU执行一个指令差不多得三步,读取指令,执行指令,写寄存器。

经典的RISC设计则是分5步:读取指令(IF),解码指令(ID),执行指令(EX),内存操作(MEM),写寄存器(WB)。我们平常用的x86的CPU有的指令可能要分将近20个步骤。

你可以理解有这么一个开关,我们啪的按一下,CPU就走一步,你按的越快CPU就走的越快。咦?听说你有个想法?少年,你这个想法很危险啊,姑且不说你有没有麒麟臂,能不能按那么快(现代的CPU也就2GHz多,大概也就一秒按个20亿下左右吧)

就算你能按那么快,虽然速度是上去了,但功耗会大大增加,发热上升稳定性下降。江湖上确实有这种玩法,名曰超频,不过新手不推荐你尝试哈。

那CPU怎么知道自己走到哪一步了呢?前面不是介绍了FF么,这个不光可以用来存中间数据,也可以用来存中间状态,也就是走到哪了。

具体的设计涉及到FSM(finite-state machine),也就是有限状态机理论,以及怎么用FF实装。这个也是很重要的一块,考试必考哈,只不过跟题目关系不大,这里就不展开讲了。

我们再继续刚才的讲,现在我们有3个指令了。我们来试试算个(1+4)X2+3吧。

0100 0001 ;寄存器存入10001 0100 ;寄存器的数字加40010 0000 ;乘20001 0011 ;再加三

太棒了,靠这台计算机我们应该可以打败所有的幼儿园小朋友,称霸大班了。而且现在我们用的是4位的,如果换成8位的CPU完全可以吊打低年级小学生了!

实际上用程序控制CPU是个挺高级的想法,再此之前计算机(器)的CPU都是单独设计的。

1969年一家日本公司BUSICOM想搞程控的计算器,而负责设计CPU的美国公司也觉得每次都重新设计CPU是个挺傻X的事,于是双方一拍即合,于1970年推出一种划时代的产品,世界上第一款微处理器4004

这个架构改变了世界,那家负责设计CPU的美国公司也一步一步成为了业界巨头。哦对了,它叫Intel,对,就是噔噔噔噔的那个。

我们把刚才的程序整理一下,

01000001000101000010000000010011

你来把它输入CPU,我去准备一下去幼儿园大班踢馆的工作。神马?等我们输完了人家小朋友掰手指都能算出来了??

没办法机器语言就是这么反人类。哦,忘记说了,这种只有01组成的语言被称之为机器语言(机器码),是CPU唯一可以理解的语言。不过你把机器语言让人读,绝对一秒变典韦,这谁也受不了。

  • 机器语言

本质上是由“0”和“1”组成的二进制数。计算机发明之初,人们只能计算机的语言去命令计算机干这干那。向计算机每发出一条指令,就要写出一串串由“0”和“1”组成的指令序列。

因此,使用机器语言是十分痛苦的,特别是在程序有错需要修改时,更是如此。而且,由于每台计算机的指令系统往往各不相同,所以,在一台计算机上执行的程序,要想在另一台计算机上执行,必须另编程序,需要进行大量重复繁琐的工作。

但在当时,由于使用的是针对特定型号计算机的语言,故而运算效率是所有语言中最高的。机器语言,是第一代计算机语言。

机器语言的优点:直接执行,速度快,资源占用少
         机器语言的缺点:难读、难编、难记、可移植性差和易出错

  • 汇编语言

为了减轻使用机器语言编程的痛苦,人们进行了一种有益的改进:用一些简洁的英文字母、符号串来替代一个特定的指令的二进制串。比如,用“ADD”代表加法。这样我们很容易读懂并理解程序在干什么,纠错及维护都变得方便了,这种程序设计语言就称为汇编语言,即第二代计算机语言。

然而计算机是不认识这些符号的,这就需要一个专门的程序,专门负责将这些符号翻译成二进制数的机器语言,这种翻译程序被称为汇编程序。
        汇编语言同样十分依赖于机器硬件,移植性不好,但效率仍十分高,针对计算机特定硬件而编制的汇编语言程序,能准确发挥计算机硬件的功能和特长,程序精炼而质量高,所以至今仍是一种常用而强有力的软件开发工具。

  • 高级语言

不论是机器语言还是汇编语言都是面向硬件的具体操作的,语言对机器的过分依赖,要求使用者必须对硬件结构及其工作原理都十分熟悉,这对非计算机专业人员是难以做到的,对于计算机的推广应用是不利的。
        计算机事业的发展,促使人们去寻求一些与人类自然语言相接近且能为计算机所接受的语意确定、规则明确、自然直观和通用易学的计算机语言。这种与自然语言相近并为计算机所接受和执行的计算机语言称高级语言。高级语言是面向用户的语言。无论何种机型的计算机,只要配备上相应的高级语言的编译或解释程序,则用该高级语言编写的程序就可以通用。

从最初与计算机交流的痛苦经历中,人们意识到,应该设计一种这样的语言,这种语言接近于数学语言或人的自然语言,同时又不依赖于计算机硬件,编出的程序能在所有机器上通用。经过努力,1954年,第一个完全脱离机器硬件的高级语言—FORTRAN问世了,40多年来,共有几百种高级语言出现,有重要意义的有几十种。其中就包括C++、java等。

高级语言的发展也经历了从早期语言到结构化程序设计语言,从面向过程到非过程化程序语言的过程。相应地,软件的开发也由最初的个体手工作坊式的封闭式生产,发展为产业化、流水线式的工业化生产。

CPU到底是怎么识别代码的?相关推荐

  1. CPU 到底是怎么识别代码的?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"加入公众号专属技术群 来源:uee.me/cERe7 最近读到这样一篇好文章,从 ...

  2. 【不懂就问】CPU 到底是怎么识别代码的?

    公众号后台回复"面试",获取精品学习资料 扫描下方海报了解专栏详情 本文来源:养码场 <Java工程师面试突击(第3季)>重磅升级,由原来的70讲增至140讲,内容扩充 ...

  3. CPU 到底是怎么认识代码的?涨姿势了!

    最近读到这样一篇好文章,从底层硬件角度出发剖析了一下CPU对代码的识别和读取,内容非常精彩,读完感觉大学里学到的很多东西瞬间联系起来了,这里分享给大家,希望能认真读完并有所收获. 首先要开始这个话题要 ...

  4. 三分钟基础:CPU 到底是怎么认识代码的?

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 每天凌晨00点00分, 第一时间与你相约 每日英文 What other people think of you is none ...

  5. CPU 到底是怎么认识代码的?

    转载自品略图书馆 http://www.pinlue.com/article/2020/05/0202/5910274786744.html 从底层硬件角度出发剖析了一下CPU对代码的识别和读取,内容 ...

  6. 入门行人重识别 尝试跑(郑哲东 简单行人重识别代码到88%准确率)过程

    来自郑哲东 简单行人重识别代码到88%准确率 运行代码和参考步骤 试运行-第一部分 prepare.py model.py train.py 试运行-第二部分 test.py 运行代码和参考步骤 代码 ...

  7. CNN网络实现手写数字(MNIST)识别 代码分析

    CNN网络实现手写数字(MNIST)识别 代码分析(自学用) Github代码源文件 本文是学习了使用Pytorch框架的CNN网络实现手写数字(MNIST)识别 #导入需要的包 import num ...

  8. 设计一款CPU到底有多难?

    文章结构 导读 一颗芯片是怎么诞生的? 一款CPU是如何设计出来的? 设计一款CPU到底难在哪里? 导读 这几天,刷遍朋友圈的新闻就是:中兴被"一剑封喉",被美国停止一切芯片进口和 ...

  9. MindSpore实现手写数字识别代码

    MindSpore是华为自研的一套AI框架,最佳匹配昇腾处理器,最大程度地发挥硬件能力.作为AI入门的LeNet手写字体识别网络,网络大小和数据集都不大,可以在CPU上面进行训练和推理.下面是基于Mi ...

最新文章

  1. Linux平台下QtCreator集成代码静态分析工具clang-tidy和Clazy
  2. 2-7-PatchesAdministration
  3. 【TensorFlow篇】--DNN初始和应用
  4. QT 中使用 c++ 的指针
  5. Magic Squares 魔板 (BFS+HASH)
  6. day60 Pyhton 框架Django 03
  7. Java中interrupted()和isInterrupted()之间的区别
  8. Python将迁移到GitHub
  9. mysql查询时间出来数字_mysql查询时间出来数字的解决方法
  10. 【kafka】消息队列设计精要
  11. unix 网络编程总结
  12. win7资源管理器从计算机开始,熟练用Win7电脑从Win7资源管理器入门
  13. C#微信、支付宝扫码支付源码
  14. 关于Android学习的三个终极问题
  15. oracle IMO史上最详细使用文档
  16. perf trace跟踪系统调用
  17. 前端必备:五大css自动化生成网站(稀有级别!)
  18. 2020-12-20随笔
  19. Groovy 和 Java 联合开发环境搭建
  20. 导出icloud照片到电脑_如何将Apple iCloud和iPhone联系人导出到Windows 10

热门文章

  1. 施乐7855打印机报错:输出纸盘偏移,关机然后开机,并通知系统管理员
  2. 【每日早报】2019/09/03
  3. matlab 动态显示图片,Matlab动态绘图、展示并保存的一种方法
  4. java类加载器—ContextClassLoader类加载器
  5. 推荐一个好的数据库工具Embarcadero DBArtisan
  6. 台达cp2000的面板怎么调节_台达CP2000系列变频器参数设置
  7. linux cp 全覆盖,Linux中使用cp命令进行强制覆盖的方法
  8. V-REP仿真Python控制机械臂和rg2夹爪
  9. UR机械臂+RG2机械手控制 学习及实际控制 系列第三篇-1
  10. qt中mysql怎么支持事务_Qt踩坑之mysql数据库不支持事务操作?