写在前面

无论你是计算机专业的学生、软件开发者,还是刚入门的小白,你都会发现一个绕不开的问题:我们每天使用的计算机,到底是怎么运行的?
CPU、内存、硬盘为什么各司其职?为什么程序运行一定要"加载进内存"?为什么不同的运算指令执行速度差异巨大?为什么 70 多年前的冯诺依曼体系结构至今仍然是计算机的基础?
这些问题的答案,都藏在最基础的计算机硬件体系结构之中
在上一篇文章中,我们了解了计算机系统的概念,还有计算机的一个发展历程。
那么在这篇文章中,我们会着重的探讨计算机硬件的一个基本组成。我们需要掌握这样的两种结构:第一种是早期的冯诺依曼结构,另一种是现代计算机所普遍采用的结构,其实也是冯诺依曼结构的一个优化。
回到源头:冯诺依曼结构诞生前的世界
如果把当代计算机比作自动化工厂,那么早期计算机(如 ENIAC)简直就是"手工作坊"。
ENIAC 的运算速度非常快,但有一个致命缺陷:每一步操作,都需要操作员手动接线告诉它下一步要做什么!
也就是说:
程序并不能通过某种方式"一次性输入",而是必须让人手把手指导它执行每一步。
想象一下:
你写一个程序:
a = 3 + 5
b = a * 7
而在 ENIAC 上执行意味着:
- 技术员 A:接一根线告诉它"做加法"
- 技术员 B:接线告诉它"输入 3 和 5"
- 执行完后再换一组线告诉它"执行乘法"
- 再接线输入 7
所以虽然这台计算机它执行运算的速度很快, 但是由于这些程序员们每一次都需要手动的接线,来告诉他下一步应该怎么做?因此,ENIAC 的计算速度就被手工操作所需要的这个耗时给抵消了。
而解决这个问题的人,是 约翰·冯·诺依曼(John von Neumann)。
为了解决这个问题,冯诺依曼这个天才,他第一次提出了存储程序的概念。
所谓存储程序,就是指可以把我们需要执行的一系列指令,以二进制代码的方式,提前把它输入到计算机的主存储器当中,也就是我们熟悉的内存里边,然后计算机会根据存储器里边存储的这一系列的指令来一条一条的执行,直到程序执行结束。
也就是说,对于 ENIAC 这台计算机,是程序员们告诉他一条指令,他就往下执行一条指令。说一句做一句,而冯诺依曼提出的存储程序的这种实现方式,就意味着我们可以把我们想要让计算机执行的一系列指令,全部一口气告诉他。
首先我们把这些指令全部先放到主存里,然后接下来会由计算机一条一条的来执行这些指令,程序员们就不需要每一步都进行手工连接的操作。这就可以大幅提升计算机的一个计算速度,那基于他提出的这个设计方案,世界上第一台具有冯诺依曼结构的计算机就诞生了:

冯诺依曼结构
冯诺依曼计算机的一个硬件结构是这个样子的:

在这个图中,我们用这种实线箭头 来表示,数据线。也就是说数据可以跟着这个实线箭头的流动方向来相互的传递传输。那像这种双箭头 就意味着两个部件之间有你来我往的这种数据传输。另外,我们会用这种虚线来表示控制线和反馈线。
来具体分析一下这个图是什么意思?
我们的计算机其实就是用来处理一些数据的,所以要让计算机处理数据,那么我们首先需要有一个输入设备。把数据输入到计算机当中 。
那这儿的数据包含我们要进行数学运算的数据,也包含了程序,也就是指令集合。所以输入设备的一个作用就是把计算机要处理的这些信息转换成机器能够识别的形式。
也就是0101这样的二进制数,那可以看到我们输入的这些数据程序,通过输入设备处理之后。这些数据事先流向了运算器,然后通过运算器的中转,才会把这些程序数据把它放到内存,也就是这儿所谓的存储器当中。所以这个存储器就是用来存放我们要处理的数据、还有程序指令的,而中间的这个运算器, 它最主要的一个功能是实现。算术运算还有逻辑运算。
算术运算 就是加减乘除那些运算逻辑,逻辑运算指的就是与或非这些运算。
那经过运算器的处理之后,这些数据的运算结果会通过输出设备把它转换成我们人类比较熟悉的形式。
另外还有一个非常重要的部件,叫控制器,控制器会用一些电信号来协调其他这些部件相互配合着工作。另外,控制器也会负责来解析存储器里存储的那些程序指令。所以我们会看到这儿有一条存储器到控制器的一个数据线,那这条数据线其实就是控制器从存储器当中读取出一条指令的一个数据流。
比如说读入的是一个加法指令还是乘法指令,那控制器解析了这条指令之后,它才会来指挥这个运算器,执行相应的加减乘除之类的运算,所以程序指令的解析是由控制器来完成的。
五⼤部件:
- 输⼊设备:将信息转换为机器可识别的⼆进制形式
- 输出设备:将结果转换为⼈可理解的形式
- 存储器:存放数据和程序指令
- 运算器:执⾏算术运算(±×÷)和逻辑运算(与或⾮)
- 控制器:解析指令并协调各部件⼯作
软件和硬件在逻辑上的等效
因此,计算机中的控制器就是用来指挥程序有条不紊的运行的,那我们输入计算机的这些数据和程序,其实就是所谓的软件的模块。
那这个框里边的这些部分,其实就是计算机的硬件部件。在计算机系统中其实软件和硬件在逻辑上是等效的。
什么意思呢?也就是说,对于同一个功能, 我们既可以用软件来实现,也可以用硬件来实现。不过,通常来说,用软件实现的成本更低,但是效率也会更低;而用硬件来实现,成本会更高,当然效率也会更高。
比如说,如果我们要实现乘法运算,那么我们。完全可以在运算器里边设计一个专门的硬件电路来实现这种乘法运算。我们只需要给出一条乘法指令,运算器就可以得到最终的结果, 但是如果我们没有这个硬件部件,其实也可以实现乘法。因为乘法其实可以用多次的加法运算来模拟,我们完全可以使用加法运算的这个指令。执行多次加法,用这样的方式来等效的模拟出乘法运算。
所以我们才说软件和硬件在逻辑上其实是等效的。显然,用硬件的方式乘法电路,直接计算肯定是更快一些。用软件的方式进行多次加法,那就需要消耗更长的时间。
冯诺依曼计算机的特点
总的来说,冯诺依曼结构的计算机有这样的一些特点:
- 组成特点:由五⼤部件构成(IO设备/存储器/运算器/控制器)
- 存储特点:指令和数据以同等地位存于存储器,可按地址寻址,指令与数据都是以二进制的形式表示。
- 指令格式:包含操作码(指明操作类型)和地址码(指明数据位置)
- ⼯作中⼼:以运算器为中⼼,所有数据传输需经运算器中转
操作码就是指明了这条指令它要进行的是什么样的操作,比如说加减乘除这些就是操作码来指明的,而地址码是指明了我们要操作的这些数据,它存放在内存的什么地址当中?那程序执行的过程中, 其实就是根据指令里边指明的地址码,对特定的一个内存单元进行访存操作的。
弗诺依曼这种结构的计算机都是会通过运算器作为中转站把它转存到这个存储器里边的。
所以,由于数据的传送必须经过运算器来完成,因此我们说这种结构是以运算器为中心,那这就产生了一个问题------我们的运算器本来是用来处理这些数据的核心部件,但是现在所有的数据中转,还需要通过它来帮忙完成,那这样的话会导致数据计算的效率降低。
现代工厂例子
来看这样的一个例子:

其实我们的计算机它本质上就是一个数据的加工厂,数据输入到计算机当中,然后处理完了之后输出。
那对于现实世界当中的加工厂呃,通常会有一个采购部门负责采购一些需要加工的原材料,那这其实就是我们输入的数据。
另外,我们会有一个生产加工的部门,对这些原材料来进行加工处理,并且还有一个部门是仓储部门,这个部门其实就是用来存放我们接下来要处理的这些原材料物资的。
当我们加工完成之后,会由销售部门把产品卖出去,另外我们还会有一个霸道总裁来负责指挥各个部门的运行。
所以在我们的这个例子当中,采购部门它采购的这些原材料本来是可以直接放到仓储部门的,但是现在他偏偏要先把这些东西先交给这个加工部门,后让加工部门再来把它转运到仓储部门去。
同样的加工完的这些产品,我们其实本来可以直接放到仓储部门,然后直接由销售部门从仓储部门。取走这些产品,但是当销售部门要取走最终的成品的时候,还需要由这个生产加工部门来进行一个中转,把这些东西交给他,那这显然是低效的。
现代计算机的结构
那讲到这儿,相信大家脑子里应该已经有一个解决方案了,解决方案很简单,那这个解决方案其实就是现代计算机的一个结构,传统的冯诺依曼结构的计算机都是以运算器作为核心数据的传输,都需要通过运算器作为中转。
但是,现代计算机通常是以存储器为中心,也就是说,输入设备它的数据是直接放到这个存储器里边的。
当运算器处理完这些数据之后,输出设备也会直接从存储器当中取走,最终的数据进行计算结果的输出。那这样的话就可以更多的解放运算器的时间,可以让运算器进行更多的运算,那我们现在使用的手机计算机基本上都是这样的一个结构。

由于运算器与控制器,它们之间的逻辑关系十分紧密,所以在大规模集成电路制作工艺出现了之后,这两个部件通常是被集成在同一个芯片上的。
整合了这两个部件的芯片就是我们现在熟悉的CPU,所以CPU里边既包含了运算器,也包含了控制器。
因此,如果把这个结构框图给简化一下,就可以表现成这样的形式。

CPU里边包含了运算器和控制器,控制器通过控制线来告诉运算器,你接下来应该执行的是加减乘除?还是什么样的运算。
另外控制器也会来控制主存储器的一个读写,还有输入输出设备的一个启动停止操作。
那主存储器和CPU之间会进行数据的交换有几种呢?
第一种就是需要参与运算的那些数据。比如xy之类的一些变量,另外一种数据就是指令。
那么指令会放到控制器当中,由控制器来解析这条指令的含义。并且发出相应的控制信号。
那最右边这个双向的箭头是说我们的IO设备也就是输入输出设备,会直接的和主存储器进行数据的交换。
主存储器和CPU统称为主机,所以我们计组里边提到的主机和大家平时熟知的这种主机是有区别的。
我们平时生活中所谓的这个主机,它里面除了CPU主存储器之外,还会包含其他的,比如硬盘啊,还有风扇啊之类的这些设备。
另外,还有一个比较容易混淆的概念就是主存与辅存。
这两个东西都可以统称为存储器。主存就是主存储器,也就是我们熟知的内存,而辅存就是辅助存储器,在电脑里边就是我们的机械硬盘,固态硬盘。
需要注意的是,虽然它们都是存储器,但是我们这儿所谓的主机是只包含了主存。而辅存我们应该把它归为IO设备,像我们平时手机里安装的APP,其实它就是存放在辅存里边的,只有这个APP需要启动运行的时候,才会把辅存里边的APP相关的程序数据代码的数据把它读到主存里边。所以辅存应该把它看作是一种IO设备。

那么计算机主机的这几个部件,它们的内部又是怎么构造的?它们之间如何协调的工作?
各个硬件的工作原理
主存储器的基本组成

存储体:
- 组成:由存储元件构成的存储单元集合
- 存储单元:每个单元存放⼀个存储字(word),具有唯⼀地址
- 存储字⻓:每个存储单元存放的⼆进制位数(常⻅8/16/32/64位)
MAR(存储地址寄存器):
- 功能:存放CPU要访问的存储单元地址
- 位数决定:存储单元总数=2的MAR位数(如4位MAR对应16个单元)
MDR(存储数据寄存器):
- 功能:暂存从存储体读出或要写⼊的数据
- 位数匹配:必须等于存储字⻓(如16位MDR对应16位存储字)
存储元件原理:
- 物理实现:利⽤电容存储电荷表示0/1
- 存储单元:多个存储元件+线路构成,地址从0开始编号
重要概念区分:
- 字(word):存储单元内容,⻓度可变(16/32/64位等)
- 字节(Byte):固定8位,⽤⼤写B表示
- ⽐特(bit):1位⼆进制,⽤⼩写b表示
- 带宽换算:100Mb/s宽带实际下载速度≈12.5MB/s(100÷8)
典型考题点:
- 根据MAR位数计算最⼤寻址范围
- 区分字/字节/⽐特的单位表示(word/Byte/bit)
- 存储字⻓与MDR位数的对应关系
主存储器里边用于存放数据的东西叫做存储体。存储体就是由一系列的存储元件来构成的,可以存放二进制0或者1。
除了存储体之外,还有两个重要的寄存器,一个叫MAR,一个叫MDR,它们分别是存储地址寄存器,还有存储数据寄存器的一个英文缩写。
寄存器就是用来存放数据的,存放二进制数据。只不过这两个寄存器,它们存放的数据各不相同,从名字可以看出MAR它应该是存放和地址相关的一些二进制数据。而MDR是用于存放实际的数据的。
刚好我今天早上去我们学校东区的地下的快递站去取快递,里面有一个快递是顺丰快递,我就觉得这个过程与我们主存储器是有很多异曲同工的地方。
在快递站里面都会多个货架,他们会给这个货架进行一个编号,什么11号货架,然后一层二层三层。
一般来说包裹编号就是根据货架号,然后在货架里的第几层,这一层的第几个包裹------用这样的规则来给我的快递编号的。
所以这家店这些一个一个的包裹货物。其实是有规律的,按照取件号摆放到货架上的,那我去取包裹的时候,我得告诉前台的店员,我的取件号是多少,店员知道取件号之后,他就可以知道我的这个包裹是存放在11号货架的第1层的第42个包裹。
于是这个店员会告诉后台的小哥让他去这个位置帮我找,于是在取件号所对应的位置就找到了,我想要的包裹。
那找到之后,他们会把我的包裹放到柜台上,我就可以从柜台上拿走我的包裹,因此菜鸟驿站的这个模型当中,货架,店员,柜台与我们主存储器的存储体,MAR,MDR这三个部分都是一一对应的,货架是用来存放货物的,然后主存储器里的存储体是用来存放数据的,那数据不就是计算机想要的货物吗?
我告诉店员我的取件号是多少,同时我的取件号也反映出了我想要的货物,它在货架上的存放位置。而对于主存储器来说,CPU想要从里边取得一个数据,那么它会把它想要的数据存放在什么位置,这个存放地址写到MAR这个寄存器当中。
那接下来主存储器是不是就可以根据MAR这儿接收到的地址信息去存储体里边拿出CPU想要的数据?
回到取快递这件事,我想要的包裹从货架上找到之后会被放到柜台上,最终我是从柜台上取走这个包裹的。那对于存储器来说也是一样,刚才CPU给他提供了一个他想要的数据的存放地址,那么主存储器里边的一些控制逻辑会根据这个地址找到他想要的数据,并把他想要的数据先写到MDR这个寄存器当中,最后CPU就可以通过数据线路从MDR当中取走他想要的数据。
所以主存储器和驿站的这个模型是有很多相通的地方的,当然也有不一样的地方,对于驿站来说,我们通常只能从呃它的货架上取走我们的包裹。
而对于存储器来说,CPU既可以从其中读出数据。同时也可以写入数据,那写入数据的过程其实和读入数据是很类似的,那CPU会指明它想要写入到哪个位置。然后他想要写入的具体数据会放在MDR当中,最后CPU会通过控制总线告诉主存储器说,这次我想要执行的操作是写操作,而不是读操作,那么主存储器根据CPU发出的这三个信息就可以往对应的位置写入CPU想要写的数据了。

那么存储体是一个什么原理呢?
我们刚才说过数据,我们要的二进制数据是存放在存储体当中的,并且是按地址来存储。
就是说我们的这个一整个存储体,它会被分成一个一个的存储单元。
每一个存储单元会存放一串二进制代码,那每一个单元里边存储的这一串二进制代码,我们就把它称为一个存储字(word)。
而每一个存储字包含多少个二进制位这个信息 我们把它称为存储字长,也就是每一个存储单元里边可以放得下多少个二进制位。
通常每一个存储单元可以存放的二进制都是8比特的整数倍,也就是八比特或者16比特或者32或者64,这是比较常见的一些存储字长。
每一个这样的存储单元会对应一个地址信息,地址是从零开始的。那这个地址信息就是刚才我们所说的MAR里边应该指明的一个信息。
如果我要读取的是第2号的存储单元,那么CPU就应该往MAR这个寄存器里边写入2这个信息。
还有一个概念叫做存储源,也就是用于存储二进制数据的电子元件。那这样的电子元件其实是用电容的原理来制造的。
不知道大家还有没有印象,我们高中里边学过电容相关的知识。电容可以用来存储电荷,因此我们可以用一个电容来存放一个二进制的比特位。那由多个存储元件,还有相应的线路,就构成了一个存储单元(关于存储元件的物理特性,我们不需要过度的深究,我们只需要知道每一个存储元件,每一个存储元可以存放一个比特就可以了)
我们说过MAR是指明了我此次要访问哪一个存储单元?是指明了存储单元的地址,所以MAR这个寄存器它的位数,它到底有几个比特位?这个信息就直接的反映了我们的存储体里边到底有多少个存储单元?
另一个方面,我们从存储单元里边取出来的数据是要放到MDR当中的,所以MDR它的二进制位数应该和存储单元是保持一致的,也就是要等于存储几次方,比如这个主存储器,它的MAR地址寄存器只有4个比特位。那么,也就意味着它的存储体里边总共只有2的4次方这么多个存储单元,因为四个2进制位最多也就只能表示这么多个数字。
也就是对应2的4次方,这么多个地址,另外如果它的MDR这个数据寄存器总共有16个比特位,那么就说明在这个主存储器当中。一个字的大小就是16个比特,换一个角度说,每一个存储单元可以存放16个二进制位,16个比特的信息。
那这儿还要给大家补充一个比较容易混淆的点。就是这儿,我们给出了所谓一个字的概念word,很多同学容易把字和字节混为一谈,那如果看英文的话,其实它们是很不一样的。但是中文的翻译确实很像一个字节,指的是8个比特位,而一个字(word)到底有多少个比特?这个具体得看我们的计算机,它的结构是怎么样的?也就说一个字的大小,有可能是16个比特,有可能8个比特,
也有可能是32或者64个比特,具体要看我们计算机硬件是怎么设计的?
那除了字和字节之外,还有一个需要强调的点,就是我们在描述一个字节的时候,经常会用1,然后加一个B。大写的b来表示。但是当我们在描述一个比特,一个二进制位的时候,一般是用1个b来表示小写的b。
所以大B和小b其实是不一样的。
那说一个大家都会有体会的生活经验,当我们去办那个宽带的时候,你会跟业务员说我要办一个100M的一个宽带,那么你会发现它的这个b是小写的b,所以它的这100M的宽带。其实指的是每秒钟可以传送100M个比特位,是这样的一个速率。
那当你用100M的宽带来下载东西的时候,我们的迅雷之类的下载器一般是以大B,也就是字节作为这种计量单位的。所以你会发现你用100M的宽带来下载东西的话,那最多就是10M多一点的,这种速度,因为你的下载器里边用的是大B,也就是字节。
其实并不是运营商骗了你,他承诺你的理论峰值100M,你把它换算成大B的话,应该是用100再除以一个八,这才是你有可能获得的最快的一个下载速度。
运算器的基本组成

核⼼部件:ALU(算术逻辑单元),通过内部复杂电路实现算术运算(加减乘除)和逻辑运算(与或⾮),是运算器中制造成本最⾼的部件
寄存器组成:
-
ACC(累加器):存放操作数或运算结果,在不同运算中作⽤不同:
- 加法:存放被加数、和
- 减法:存放被减数、差
- 乘法:存放乘积⾼位
- 除法:存放被除数、余数
-
MQ(乘商寄存器):专⽤于乘除法运算:
- 乘法:存放乘数、乘积低位
- 除法:存放商
-
X(通⽤寄存器):可存在多个,⽤于存放各类操作数(如加法中的加数、减法中的减数等)
运算器最主要的部件有这样的四个ACC,ALU, MQ,还有一个叫X。
之前,我们说过运算器就是要来实现算术运算加减乘除,还有逻辑运算的。
其中ACC它其实是一个寄存器,翻译为中文一般叫做累加器。累加器可以用来存放进行加减乘除或者逻辑运算的那些操作数,同时也会用于存放运算的结果。
第二个寄存器叫MQ,就是乘商寄存器。乘和商其实也就对应着乘法和除法,所以顾名思义,这个寄存器只会在乘法除法运算的时候才会用得到,同样的,会用来存放乘法除法的操作数或者运算的一个结果
第三个寄存器X,它叫通用的操作数寄存器,或者我们可以把它简称为通用寄存器。
其实这种通用寄存器一般在运算器里边可能会有多个,但理论上我们只需要有一个通用寄存器就可以实现我们想要的那些算术运算。
最后这个长相很不一样的家伙ALU,它叫算术逻辑单元。那LU才是运算器的核心部件,它里边集成了一些复杂的电路。用这些复杂的电路可以实现算术,运算或者逻辑运算,前边我们说的这三个寄存器其实就是用来存放一些数据的。这些寄存器的硬件构造并不复杂,而ALU的硬件构造就很复杂了。
所以运算器里制造成本最高的一个部件就是ALU。

控制器的基本组成
核⼼部件:
- CU(控制单元):分析指令并发出控制信号,类⽐"霸道总裁的CEO"
- IR(指令寄存器):存放当前正在执⾏的指令
- PC(程序计数器):存放下⼀条指令地址,具有⾃动加1功能
指令执⾏三阶段:
- 取指令:根据PC地址从内存取出指令
- 分析指令:CU解析IR中的指令内容
- 执⾏指令:CU控制其他部件完成操作
阶段简化分类:
- 取指阶段(合并前两阶段)
- 执⾏阶段(最后阶段)

控制器里边有三个必不可少的部件,一个叫CU,也就是控制单元。
控制单元是控制器里边最核心的一个部件。它里边也集成了很复杂的一系列的电路,可以完成分析指令,并且可以给其他的部件发出一些控制信号。
所以之前我们把控制器比喻成霸道总裁,它会控制其他的部件,但是对于这个霸道总裁来说CU才是他真正的核心。就相当于CU是霸道总裁的老婆,其实总裁还是得听老婆的好。
那除了CU之外,还有另外的两个寄存器,IR是指令寄存器,就是用来存放当前执行的指令的。
PC,是程序计数器,它是program counter的一个缩写。这个寄存器的作用是用来存放下一条指令的地址,并且有自动加一的功能
我们的计算机最主要的工作就是执行代码,而所谓的代码其实就是一条一条的指令,那每完成一条指令,需要分为这样的三个阶段:
第一个阶段是取指令会根据PC,也就是程序计数器里边所记录的这个指令地址,根据这个地址,从内存里边取出那一条指令,那取出的指令会被放在IR,也就是指令寄存器当中。
第二个阶段就是CU这个部件开始分析这条指令到底是要干什么的。
第三个阶段就是当CU分析完了之后,CU这个部件就会控制着其他部件来配合着完成指令的具体执行。
很多地方也会把前边的这两个阶段统一的称为取指的阶段,然后最后的这个阶段把它称为执行的阶段。我们计算机区分指令和数据的关键,就在于其访问的阶段不同,这里的阶段就是这两个阶段(后面例子可以看清)
理解计算机的工作过程
我们以下面一个简单的代码例子来帮助我们理解计算机的工作过程:

这个程序里面只是执行了一句简单的代码y=a×b+c,这是我们高级语言程序员看到的一个视角。
但事实上,我们的CPU不可能一次性完成这样的一个复合运算,它只能先进行乘法,然后再进行加法。
所以我们这段程序在经过编译链接一系列的骚操作之后,可以把这个高级语言翻译成机器能读得懂的机器语言。同时,会把这段程序装入主存,那它在主存里的样子就是这样的:

左边的这一列是主存的地址,从1到8号。
那我们定义了a,b,c,x这样的四个变量,我们a这个变量,它是存放在地址为五的,这个存储单元当中的。当然,在主存当中,是以二进制的形式来存放的。
那b,这个数据是存放在6;c,存放在7,然后最后我们要计算的这个y。它是存放在8这个存储单元当中。
那除了这些数据之外,前边0到4这几个存储单元存储的就是我们这一段程序它所对应的机器指令。
可以看见,我们用高级语言写的,短短的一行代码,经过编译之后丢给计算机的,其实是这么多条复杂的指令。
那每一条指令会分为操作码和地址码这样的两个部分,我们这儿每一个存储单元是16个比特。也就是存储字长为16个比特,然后每一条指令它的两个部分,总共也是占16个比特。只不过,在执行这些指令的时候CPU会自动的把它们拆解成操作码和地址码。
下面我们来模拟运行了这个程序:
1、最开始时,我们的PC,也就是程序计数器会指向一开始的地址,也就是对应的0号地址

随后,我们会通过PC存储的地址,找到主存储器的MAR,也就是存储地址寄存器,告诉他我们要找的指令的地址是0,导致MAR的值变为地址的0.
2、同时,控制器会通过控制总线告诉主存储器,说我这次要进行的是读操作,那接下来主存储器会根据MAR记录的这个地址信息去存储体里边。找出0号地址所对应的这些二进制数据。
3、随后从存储体中取出数据,放到MDR寄存器中
4、此时我们就获取到了想要拿到的指令,于是我们就把这个指令给IR指令寄存器,表示这个是当前执行的指令
5、IR已经存放了此次要执行的指令,接下来这条指令的前6个比特,也就是操作码会被送到CU控制单元里边。CU会分析这个操作码,就可以知道它对应的是一条取数的指令。
6、所以接下来要把这个地址码所指明的内存单元里的这个数据把它给取出来,并且放到ACC这个寄存器当中,这是取数指令要做的事情。那既然要读取主存的这个地址的信息,于是就需要把这个地址码放到主存的MAR当中。这就导致此时MAR是等于五,因为这个二进制数转换成十进制就是5。那5号存储单元所指向的刚好就是a这个变量。
7、此时又开始根据MAR中的数据,前往存储体中获取数据
8、把拿到的数据存放在MDR存储数据寄存器中
9、从MDR中把数据存放到运算器中的ACC累加器中

此时,就完成了对第一个取数指令的分析与执行。
之前我们说过程序计数器PC,它有自动加一的功能,这个加一的操作并不是在整个指令完成后才加一,其实在取指令这个动作完成之后PC的值就会自动的加一了,它以前是零,那自动加1,它就会指向1,也就是指明了下一条我们要执行的指令,应该是在1这个单元这。
所以之前这条指定执行之后导致的效果就是PC,此时等于1,ACC成功=2,也就是等于a的值。
接下来,根据程序计数器PC所指向的位置取得第2条指令。
那么,取指令的过程和之前是类似的,也是刚刚的1、2、3、4这四个步骤,取到IR指令寄存器中。
那取完指令之后就需要分析指令,就和之前一样会把操作码这个部分送到CU控制单元,然后经过CU分析之后,它可以知道000100这个操作码对应的是一个乘法操作,所以这是一条乘法指令,因此接下来CPU会指挥其他部件来协调的完成这个乘法操作。
还记不记得我们写的程序y=a×b+c,现在这一步,我们要完成的是a×b的操作,而a这个变量之前已经被我们送到ACC这个寄存器里边了,所以现在这条乘法指令它的地址码指明的是另一个乘数b,它的存放位置。
那b存放在6这个位置,刚好这个地址码把它翻译成十进制数也是等于6。所以这条指令的地址码会被送到MAR当中,指明我要取出的是六号存储单元里边的数据。所以接下来主存会根据MAR所指明的这些地址,取出相应的这个数据。也就是把b这个变量的值放到了MDR当中。接下来b的值会从MDR再通过数据总线送到MQ, 也就是乘商寄存器当中。
而当b的值放到MQ里面后,接下来还需要把a的值先放到通用寄存器x当中,也就说当这个CPU执行乘法操作的时候,它会把被乘数放到x这个通用寄存器里边,然后把乘数放到MQ这个乘商寄存器里边。接下来CPU会通过控制线告诉ALU算术逻辑单元,让它进行乘法运算。
那ALU会把X和MQ里边存储的这两个数,把它们进行一个相乘的操作,然后把最终乘得的结果放到ACC里边。那这个操作导致ACC里边得到了a×b的值为6。
在我们这个例子当中, 进行相乘的这两个数很小,但是如果说这两个数很大的话,那么有可能ACC这个寄存器里边是存不下的。这种情况下就需要MQ乘商寄存器的一个辅助存储。MQ里边会用来存放乘法运算结果的低位。
这样我们就完成了第二条指令,也就是乘法指令,那大家会发现和前边那条指令相比,其实第一步到第五步这几个步骤。每一步要做的事情都是一模一样的,只有当CEO控制单元分析出这条指令是乘法指令的时候。接下来的操作就会产生一些区别。
另外,和之前说的一样,当取指令结束之后PC的值也会自动加1,所以。这条指令执行结束之后,得到的效果就是PC指向了2,也就指向了下一条要执行的指令.

后面的操作也是同理:



相信通过这个例子,大家就能够真正的理解运算器,控制器和主存储器,它们的各个部件分别有什么作用?它们之间是如何相互协调着来工作的?
总结
我们说主存,运算器,控制器这三大部件构成了主机,那这三大部件的内部又分别有一些细分的小的部件,每一个部件完成了不一样的功能。但是相信通过之前的那个程序运行的例子。大家能够体会到每一个部件的具体作用。运算器的核心部件是ALU,控制器的核心部件是CU,那在CPU里边这两个部件的制造成本也是最高的。
另外,关于存储体里边所涉及的这些概念,大家也一定要捋清楚,这些都是选择题的高频考点。
需要注意字和字节的区别。也需要注意,大B和小b的一个区别。
我们用一个程序的执行来说明了计算机的一个工作过程。刚开始,我们需要把指令和数据把它们存到主存里边,然后PC程序计数器会指向第一条指令在内存中的存放地址。接下来就是对一条一条指令的执行,首先需要从主存中取出一条指令,放到IR指令寄存器当中,同时PC+1指向下一条应该执行的指令。
接下来CU会分析指令,根据指令的操作码来确定这条指令应该做一些什么具体的事情。那最后CPU会指挥其他的部件来共同的配合着完成这条指令的执行,那这就是我们计算机的一个工作过程。
另外再补充一点,MAR和MDR这两个寄存器,它逻辑上是属于主存的,但是其实现代的计算机当中,这两个寄存器通常会被集成到CPU里边,所以如果接下来的学习当中大家看到了MAR和MDR这两个寄存器,被我们画到了CPU这个部件里边,也不要觉得奇怪。
计算机的运行,从来都不是什么神秘魔法。从早期的插线编程,到如今我们指尖触发的瞬息响应,其背后是一套精密、严谨且优雅的硬件逻辑在默默支撑。
正如我们所见,一个简单的 y = a × b + c 在高级语言中只是一行代码,但在计算机底层,却需要控制器、运算器、存储器等多个部件,历经"取指、分析、执行"的精密协作,才能一步步完成。CPU 不会理解"乘法"是什么,它只知道当操作码是 000100 时,需要激活特定的电路,将特定寄存器里的数据进行特定计算。
现代计算机的结构,是冯·诺依曼天才思想的延续与优化。它本质上是一个以 存储器为中心 的自动机:程序和数据被预先存入内存,由 程序计数器(PC) 指引方向,由 控制器(CU) 发号施令,由 运算器(ALU) 执行计算,最终通过 地址寄存器(MAR) 和 数据寄存器(MDR) 精准地进行着每一次数据交接。
理解这个过程,不仅是为了应对考试,更是为了建立起一种 "计算机思维" ------ 当你再写下一行代码时,能仿佛看到指令流在总线上的奔涌,数据在寄存器间的流转,以及控制器发出的那些无形的电信号。这种从逻辑门到高级抽象的贯通感,是解开计算机科学所有后续奥秘的第一把钥匙。
希望这篇文章,能帮你推开这扇门。硬件世界的故事,才刚刚开始。