计算机CPU工作原理及汇编语言简介(链接)
 
     从微信公众号把原文直接复制过来,发现图片、表格经常丢失,只有纯文字,所以建议直接点击上述链接阅读。

复制过来的纯文字内容如下(图片、表格丢失,格式错乱):

在之前的文章中, 基于“冯诺依曼结构”,我们制作了一台简易计算机,如下图所示:

其中有CPU的影子:
       a. U3加法器对应CPU运算器。
      b. U1计数器、U4触发器、时钟信号、U5非门,这四个部件对应CPU控制器。
      深入理解这个简易计算机的工作流程,有助于理解CPU的工作原理(本文会讲述)。

我们可以继续用proteus来画更复杂的电路图,并自定义CPU指令集,实现更强大的功能。
      然而,无论我们怎么设计电路来制作CPU,它永远只是冰山一角的一个小小冰点, 离Intel或AMD的商用CPU有太远太远的距离。我们不可能也没必要画出那么复杂的CPU(几十亿个晶体管器件)。
      因此,我们需要从底层复杂的电路图设计中解脱出来,站在更高的层次和更高的抽象度上来看待CPU.

CPU是Central Processing Unit的缩写, 翻译过来就是中央处理器,看这名字,就知道它是很重要的东西。本文在叙述时,有的地方用CPU,有的地方用微处理,它们都是一个意思。

本文主要分为三个部分:

CPU发展历史

CPU工作原理及8086CPU简介

汇编语言简介

一. CPU发展历史
      1947年,那是一个冬天,有三位牛人,在贝尔实验室发明了晶体管,神话般的传说......
      1948年,他们申请了专利,并于1956年获得了诺贝尔物理学奖。肖克利和仙童“八叛逆”的事情,我们之前已经讲过,故不再展开介绍。
      1968年,“八叛逆”中的罗伯特诺依斯和戈登摩尔,以及安迪格鲁夫共同创立了鼎鼎大名的Intel公司。大家应该对这三个人略有耳闻:罗伯特诺依斯曾陪乔布斯解惑伤心往事;戈登摩尔发明了沿用至今的摩尔定律;安迪格鲁夫写过一本书叫《只有偏执狂才能生存》。
      1971年,又是一个冬天,Intel工程师特德霍夫,发明了世界上第一款商用微处理器4004,它是一个通用的微处理器,内部集成了2250个晶体管,有45条指令,每秒运算6万次。特德霍夫被英国《经济学家》杂志称为“二战以来最有影响力的科学家之一”。Intel CEO戈登摩尔将4004称为"人类历史上最具革新性的产品之一"。
       4004微处理器外观图如下:

后来,Intel又研发了经典的8086微处理器,本文会对8086微处理器进行具体介绍,故暂且不表。

事实上,在那个年代, 有很多公司都参与了微处理器的研发,Intel只是其中的典型代表之一,我们不对所有的微处理器进行介绍,仅来看一下Intel微处理器的发展历程,如下表所示:

我此刻写公众号文章,正在使用的电脑的CPU芯片,就是Intel公司的Pentium(奔腾)型号:

二. CPU工作原理及8086CPU简介

我们来审视一下自制的简易计算机,其根本部件就是CPU和存储器,我们来看看CPU如何与内存进行交互:

a. 地址线:指定数据在内存中所在的地址

b. 数据线:指定数据的值具体是多少

c. 控制线:指定控制信号(控制信号的种类非常多),比如指定究竟是从内存中读出数据,还是向内存中写入数据。

来看一下CPU从内存中读取数据的过程。例如:从地址为3的内存单元中读出数据,读出的数据是8,如下图所示:

再看CPU向内存中写入数据,也是类似的逻辑。例如,把数据8写入到地址为3的内存单元中,如下图所示:

来看CPU如何传递地址信息。下图中CPU有10根地址线,因此可以对应1024个内存单元(每个内存单元是1B),所以,我们可以说这个CPU的寻址能力是1KB.

来看一下CPU如何传递数据信息。对于8088CPU而言,有8根数据线。所以,传送16位二进制数据时,需要操作两次,如下图所示:

而8086CPU中有16跟数据线,所以,传送16位二进制数据,只需要一次即可,如下图所示:

下图是CPU和各类存储器的连接逻辑图:

从CPU的角度看,CPU将系统各类存储器看作是一个逻辑存储器,如下图所示:

以8086CPU为例,它的地址线有20根,故8086CPU的寻址能力是1MB, 其对应的地址空间就是00000H~FFFFFH, 总共能对应2^20个内存单元,如下图所示:

我们来具体看看CPU是如何与内存交互的,如下图所示:

CPU的主要工作流程如下:

a. 读取指令:控制器的PC中,存储了待执行指令的地址,并根据这个地址,从内存的代码段读出指令内容,存放到IR中。

b. 指令译码:控制器中译码电路,对IR中的指令内容进行译码,确定究竟该执行什么操作。注意,在指令译码后,还需要更新PC, 使得PC指向下一条指令,便于让CPU不知疲倦周而复始地工作。

c.  执行指令:根据指令译码的结果,可能会去内存的数据段读取数据,传到寄存器中,进而传递到运算器,进行运算。运算之后,可能需要把数据结果写回到内存的数据段。

CPU三“步”曲如下:

海可枯,石可烂,天可崩,地可裂,但这种循环永不改变。CPU完全按照人写的程序指令,来执行任务,它本身没有任何智能和思维。

而且,我们应该注意到:在“冯诺依曼结构”中,指令和数据都存放在内存中,具有同等的地位。对于内存而言,里面存放的无非就是二进制数字,至于这些数字表示的是指令还是数据,内存自身并不能区分。这些数字的含义,取决于读取者CPU怎么理解。比如,CPU将程序计数器PC指向的内容理解为指令,而在其它场景,可能就理解为数据。

所以,在数据线上传输的内容,可能是数据(程序数据),也可能是指令(程序指令)。它们都是广义上的数据。

思考一下这个问题:如果强制让PC指向内存的数据段,会怎样呢?显然,CPU仍然把数据当做指令来处理,当然这个指令也有可能超出CPU指令集的范围,无法正常执行。

我们已经介绍了通用CPU的工作原理,若要更深入理解并操作CPU, 还是得针对具体型号的CPU. 以经典的8086CPU为例,  其外观图如下:

8086CPU外部引脚图如下:

8086CPU内部结构图如下:

简单总结一下8086CPU:

a. 8086CPU包括控制器和运算器,还有14个寄存器。部分寄存器起到了控制的作用,所以,可以归纳为属于控制器。这14个寄存器都是16位的,它们是:

b. 8086CPU有20根地址线,因此,可以对应2^20个存储单元(1个存储单元是1B), 所以,8086的寻址能力是1MB.  我们知道,8086CPU的寄存器是16位的,那如何给20根地址线提供数据的呢?很显然,可以考虑用两个寄存器(比如CS和IP)。在叙述通用CPU时,一般用PC来表示程序计数器,8086CPU是一种具体的CPU, 其实现PC的方式是CS:IP, 即有PC = CS * 16 + IP, 如下所示:

c. 8086CPU有16根数据线,一次就可以传送16位二进制数据,如下:

d. 字长是CPU一次能处理的数据的位数,通常与寄存器位数有关。前面已经说过,8086CPU的寄存器都是16位的,所以,8086CPU的字长就是16位。来看看AX如何存储16位二进制数据:

我们大致熟悉了8086CPU的结构,现在问题是,怎么操作和使用它呢?钻到里面去用手掰弄开关吗?显然不行,因为你我根本钻不进去。
      还是得请机器语言0和1出场了,机器语言完全由一系列的0和1组成,非常不好懂,而且容易出错,也很难排查错误,烦人得很,看一眼就头晕:

如果对机器语言还心存幻想, 不妨看看下面这段机器语言程序,它的功能是在屏幕上输出"welcome to masm":

其中0和1不能有一丁点错误。一个正常的人,是没法忍受机器语言程序的。而且,如今这个年代,已经几乎没有人用机器语言来编写程序了。机器语言繁琐,需要用汇编语言来简化编程。

在之前的文章中,我们说过,人写了汇编语言后,需要经过汇编器工具的转换,自动生成天书般的机器语言,过程如下:

所以,我们还是用汇编语言来辅助描述CPU的执行流程吧。
 
       在了解8086CPU是如何执行指令前,我来提一个问题:CPU的指令集存放在哪里?
      有人说,CPU指令集存放在CPU中,有人说,存放在内存中。这有点搞笑了
      CPU指令集存放在CPU的使用手册中。所谓的CPU指令集,就是操作CPU的方法,这些操作方法,当然是存在于CPU使用手册中。而这些操作方法,则具体是由CPU的电路来实现的。

我们来看8086CPU是如何执行程序指令的,以如下汇编指令为例:
mov ax, 0123h
mov bx, 0003h
mov ax, bx
add ax, bx
       这些汇编指令,与机制语言指令是对应的,它们以二进制的方式存储在内存中。为了方便阅读,我们以十六进制的方式进行展示,如下图所示:

下面,来看看8086CPU执行这段指令的过程。
       初始状态如下(CS = 2000H, 图中标注的是十六进制):

执行地址加法(注意PC = CS * 16 + IP, 这里的16就是10H):

于是,PC =20000H,如下:

用地址总线来传递PC的值:

从内存中读出数据(指令),对应的机器语言指令的十六进制是B8 23 01,其汇编指令是mov ax, 0123H , 如下:

把这条指令存储到指令缓冲器(即我们前面提到的指令寄存器IR),  然后,译码电路完成译码功能。指令缓冲器中的指令内容如下:

然后IP会变化,PC也就随之变化了,指向下一条指令,如下:

现在开始执行IR中的指令(mov ax, 0123H),如下:

执行后的结果是:

到此为止, CPU已经完整地执行了第一条指令:mov ax, 0123H,  可以看到,CPU似乎又回到了初始状态,不同之处是,现在IP = 0003H, 也就是说,PC指向了下一条指令。

接下来的CPU执行流程,就很俗套了,无非就是重复再重复而已。我们不详细介绍每个细节,直接给出重要步骤的结果:

终于,我们得到了结果,如此简单而清晰:

通过上面的分析,我们很容易理解8086CPU的具体工作过程。可以看到:
      CPU周而复始地执行人设定的指令(程序),CPU并不智能,也不具备思考能力,它就是个干蛮力、干苦力的家伙,一根筋干到底。这种枯燥无味的繁重工作,就应该让CPU去做,而且,它还几乎不会犯错。可以说,CPU解放了生产力,解放了全人类。

三. 汇编语言简介
      我们已经讲述了8086CPU执行指令的具体过程, 但仍然会有这样一个疑问:

在各种高级语言琳琅满目的21世纪,很少有人用汇编语言进行编程,汇编语言开发效率低,而且还不可移植。那么,我们为什么还需要了解和学习汇编语言呢?

其实,我们学习汇编语言,不是为了用汇编语言去编写大型的程序和软件,而是因为:

a. 汇编语言是直接操作计算机硬件的语言,通过汇编语言编程,可以获取底层编程的感觉。直接指挥控制计算机,这种感觉很奇妙。通过汇编语言,可以深入理解计算机的工作原理,对后续学习计算机的其它课程(比如操作系统)很有好处。熟悉汇编语言,也能提升自信,偶尔还可以在闲谈聊天时吹水。
      b. 我们在用高级语言编写软件程序时,经常需要调试,有时候需要跟踪到汇编语言这一层,才能明白问题之所在,汇编语言是最后的一根救命稻草。
      c. 在进行性能优化时,需要用到汇编语言。对于多数程序员而言,是不需要用汇编语言进行性能优化的。但是,当我们看操作系统或优秀开源组件的源码时,会经常看到汇编语言代码,如果我们熟悉汇编语言,至少能读懂,那么也就不害怕了。

在学习汇编语言之前,我们先来看一下与汇编语言有关的几个基本问题:
      a. 同一CPU的汇编语言和机器语言是一一对应的吗?
      由于汇编规范可以有多种(比如Intel汇编规范和AT&T汇编规范),所以,机器语言可能有不同的汇编语言形式。可以这么说,当汇编规范确定后,机器语言和汇编语言是一一对应的。
      b. 汇编语言是CPU厂商规定的吗?
      CPU厂商只负责设计和制作CPU的电路硬件部分,并提供手册告诉使用方如何来操作CPU. 这个手册中,必须提供操作CPU的机器语言, 一般也会提供其对应的简记方式(汇编助记符), 编译器厂商拿到这个汇编助记符手册,定义汇编语言规范,开发对应的汇编器,把汇编语言程序转化为CPU厂商要求的机器语言程序。所以,汇编语言是编译器厂商根据CPU厂商的指令集说明书来规定的。需要补充说明一点,CPU厂商通常也会提供SDK,方便使用CPU.
      c. 汇编语言为什么不具有可移植性?
      我们自制简易计算机的CPU和8086CPU的电路结构不一样, 所以,操作方式不同(指令集不同),机器语言也不同,汇编语言也不同。因此,汇编语言不具备移植性。你辛辛苦苦地写好汇编语言程序后,只能在某款CPU上运行,没法在其它类型指令集的CPU上运行,挺尴尬的,这也是汇编语言的局限性之一。

学习汇编语言,一定要动手实际操作。可以采用masm(Windows平台)或者nasm(Linux平台)作为汇编器工具。如果是在Windows平台上,可以在dos中进行debug,嗯,就是那个命令行黑框框:

这些命令行式的东西,不直观,不好用。直到遇到Windows平台上的emu8086界面工具, 才知道什么叫相见恨晚,如下:

工欲善其事,必先利其器。建议在学习汇编语言时,使用emu8086这种界面工具,它是所见即所得的。工具的安装和使用很简单,基本都是傻瓜式的操作,故无需介绍。

现在开始用emu8086工具来介绍汇编语言。
      之前用自制简易计算机实现了连续加法(1+2+3+4+5),那该如何针对8086CPU编写汇编语言,来实现这个连续加法呢?如下:
assume cs:code

code segment
  mov ax, 0  
  add ax, 1
  add ax, 2
  add ax, 3
  add ax, 4
  add ax, 5
  
  mov ax, 4c00h
  int 21h    
code ends

end
      我们来看下emu8086的初始状态,盯住CS和IP, 它是程序执行的起点,如下图:

可以看到, CS = 0100H, IP = 0000H, 所以,即将执行的汇编指令是:
mov ax, 0

我们利用emu8086工具来做单步调试,能看到CPU内部每一步操作的详细信息,当add ax, 5 执行完毕后,可以看到,ax的值是000FH, 也就是十进制的15,如下所示:

这个程序中的语句,比较简单,所以,我们不做详细解释。

1加到5很简单,如果要计算1加到100呢?难道要把add ax重复写100遍吗?显然不是,直接用循环指令吧,汇编语言程序如下:
assume cs:code

code segment
  mov ax, 0  
  mov bx, 0   
  mov cx, 100
  
  label:  
  inc bx
  add ax, bx
  loop label
  
  mov ax, 4c00h
  int 21h    
code ends

end
      执行完毕后,ax = 13BAH, 也就是十进制的5050, 和高斯小朋友当年算出的结果完全一致,如下:

这个程序中的每条语句,也比较简单,毕竟都是语法层面的玩意儿,所以,就不一一解读了。

至此,我们基本了解了汇编语言,至于汇编语言进阶的学习,那也不难,有emu8086在手,还担心什么呢?建议有兴趣的朋友,多多演练和调试。

我们来总结一下本文内容:
       首先,我们简要介绍了CPU的发展历史。
       然后,我们介绍了CPU的工作原理,并对8086CPU执行程序指令做了详细讲解。
       最后,我们讲了汇编语言的重要性和必要性,并用简单的示例,进行汇编语言入门级的演练。

还是那句话,我们了解和学习汇编语言,绝不是为了将来用汇编语言去编写软件程序,而是为了深入理解计算机的工作原理。
      从电路操作开始,我们的关注点在电路层面,当电路复杂后,感觉控制电路已经力不从心了。
      于是,我们开始用机器语言来控制电路, 一串串的0和1组成的机器语言,可以控制电路,但天书般的机器语言,已经让我们眼花缭乱。
      于是,我们开始用汇编语言来控制电路, 我们需要操作CPU的每个部件,告诉CPU电路如何去执行指令, 这种过程,依然是心力交瘁的感觉。看下图来感受一下对比,那么多杂乱的机器语言和汇编语言, 被高级语言(C语言)一行简单代码就搞定了:

从直接掰弄开关来操作电路,到机器语言,到汇编语言,再到高级语言(比如C语言),这是一个不断远离具体细节、不断进行抽象、不断接近事物本质的过程。在这种不断的抽象过程中,编写程序的人,从繁琐中得以解脱,编写程序的效率得到了提升。那些繁琐的步骤,还是交给编译器工具和汇编器工具吧。

我们已经详细介绍了8086CPU, 然而,它只是微处理器,不包含RAM和ROM, 因此,8086CPU不是一台完整的计算机。在后续文章中,我们会介绍一台完整的计算机(8051单片机),并用高级语言(C语言)来编写程序,达到控制单片机的目的。

单片机和C语言,不见不散

计算机CPU工作原理及汇编语言简介相关推荐

  1. 计算机原理学习(1)-- 冯诺依曼体系和CPU工作原理

    前言 对于我们80后来说,最早接触计算机应该是在95年左右,那个时候最流行的一个词语是多媒体. 依旧记得当时在同学家看同学输入几个DOS命令就成功的打开了一个游戏,当时实在是佩服的五体投地.因为对我来 ...

  2. 计算机多核启动原理,多核cpu工作原理 不进来看看?

    cpu是一个对电脑来说非常重要的配件,所以在关于它的知识上朋友们可千万要注意,所以今天小编想为大家讲的是多核cpu工作原理的相关内容,喜欢的朋友们赶紧收藏,相信对大家会有帮助. 多核cpu工作原理 1 ...

  3. 计算机CPU工作(多核/缓存)原理

    现代CPU一般使用缓存(Cache)来解决CPU读写主存慢的问题:使用多核来并行计算以加速程序运行.并行计算一般需要多线程技术,如何操作多线程对编程人员提出了挑战. 计算机软硬件体系结构 之前的文章 ...

  4. 寄存器(CPU工作原理)04 - 零基础入门学习汇编语言09

    第二章:寄存器(CPU工作原理)04 让编程改变世界 Change the world by program 段的概念 错误认识: 内存被划分成了一个一个的段,每一个段有一个段地址. 其实是: 内存并 ...

  5. 一文了解二进制和CPU工作原理

    Part 1. 原来,我们是这样记数的 " 本节内容节选自下方 参考资料 1 在讨论「二进制」和「CPU 如何工作」之前,我们先来讨论一下我们生活中最稀疏平常的 数字,我们与之频繁地打交道: ...

  6. 「MoreThanJava」一文了解二进制和CPU工作原理

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  7. 一文读懂CPU工作原理、程序是如何在单片机内执行的、指令格式之操作码地址码

    文章较长,大家可选择性阅读,嘎嘎细 计算机结构 CPU的运行原理 CPU的控制单元在时序脉冲的作用下,将指令计数器里所指向的指令地址(这个地址是在内存里的)送到地址总线上去,然后CPU将这个地址里的指 ...

  8. 简要分析计算机的工作过程,计算机的工作原理.doc

    第 周 星期 第 节 年 月 日 课 题 计算机的工作原理 教 学 目 标 1.知道计算机系统的组成 2.知道计算机系统的工作原理 教材分析 重点 计算机系统的工作原理 难点 计算机系统的工作原理 教 ...

  9. 现在使用计算机的工作原理是,计算机的工作原理是什么

    很多人都会用电脑,那么你知道吗小编总结了一些资料,供大家参考! 计算机的基本原理是存贮程序和程序控制 预先要把指挥计算机如何进行操作的指令序列***称为程序***和原始数据通过输入设备输送到计算机内存 ...

最新文章

  1. Oracle事务的隔离
  2. 2.UiSelector API 详细介绍
  3. php如何判断是否关注,php如何判断用户是否关注微信公众号
  4. ant design vue 树形控件_官宣!vue.ant.design 低调上线
  5. u boot 驱动完成
  6. 成年人不懂这些道理,会吃很多亏
  7. 从报表到大数据分析,BI工具如何提高用户体验
  8. kubernetes kubeadm init this version of kubeadm only supports deploying clusters kubeadm版本降级
  9. Intellij IDEA创建包(package)问题解决方案
  10. js基础-21-事件委托
  11. python王者荣耀
  12. 新手入门|计算机科普
  13. android iphone滑动解锁,苹果iOS10锁屏详解:“滑动来解锁”已成为过去
  14. Linux内核分析学习路线总结(内核人员必看)
  15. 雨后小故事动态邪恶_当您遇到“邪恶”的问题时,使故事变小
  16. 大学计算机应用教程实验步骤,大学计算机基础实验教程--详细介绍
  17. 如果把ChatGPT和“挖呀挖”的黄老师结合起来,她可以为你做什么事情?
  18. 报错:实体名称必须紧跟在 '' 后面
  19. 自定义SpringBoot程序启动图标
  20. pip高阶玩法,让python模块安装飞起来

热门文章

  1. 【转载】无线电干扰分类
  2. 离散基础 (14). 驻点极值和最值问题
  3. 使用Dymola的Python接口
  4. 自主命题计算机专业课,计算机专业考研统考是所有的科目都统考还是专业课统考?...
  5. 与游戏世界交互——Hit UFO
  6. svn提交数据失败的原因和解决办法
  7. 快手实操经验,如何快速玩转快手直播带货
  8. 如何选择客流统计分析系统
  9. 计算机建模报告,计算机三维建模及析实验报告单.doc
  10. Redisson 概述:什么是Redisson ,Redisson 能干什么