概述
- 现代计算机的基本构成都是基于冯诺依曼结构的思想来设计的, 主要有五大硬件部件
- 我们研究下主机内部的三个硬件部件:主存储器,运算器,控制器的内部细节
- 三者之间是如何协调工作的
主存储器

- 主存储器里面用于存放数据的东西叫做存储体
- 存储体就是由一系列的存储元件来构成的, 可以存放二进制0或1
- 除了存储体之外还有两个重要的寄存器:MAR 和 MDR
- MAR:存储地址寄存器(Memory Address Register)
- 存放和地址相关的一些二进制数据
- MDR:存储数据寄存器(Memory Data Register)
- 存放实际的数据的
- 寄存器是用来存放二进制数据的, 只不过这两个寄存器它们存放的数据都不相同
- MAR:存储地址寄存器(Memory Address Register)
案例解释
- 菜鸟驿站它的一个基本组成,其实和我们组存储器是有很多异曲同工的地方,每一个菜鸟驿站里面都会有一个货架
- 他们会给这个货架进行一个编号,比如:11号货架,然后1层2层3层,快递到了菜鸟驿站存放会按照此类来编号存放
- 可以看到,这些一个一个的包裹其实是有规律的,按照取件号摆放到货架上的, 当我取包裹时,告诉店员我的取件编码是多少
- 店员根据我的取件编码来找我的包裹,也就是寻址,当找到包裹后交到柜台,我在柜台就顺利取到了包裹
- 菜鸟驿站的这个模型当中,货架,店员和柜台与我们主存储器的三个部分,都是一一对应的
- 菜鸟驿站的货架是用来存放货物的一个个的包裹, 主存储器的存储体是用来存放数据的
- 而数据就是计算机想要的货物,另外我会告诉店员我的取件号是多少,同时我的取件号也反映出了我想要的货物在货架上的存放位置。
- 而对于主存储器来说,CPU想要从里边取得一个数据,那么它会把它想要的数据存放在什么位置, 也就是存放地址写到MAR这个寄存器当中
- 那接下来主存储器就可以根据MAR接收到的地址信息去存储体里边拿出CPU想要的数据
- 在菜鸟驿站的比喻中,我想要的包裹从货架上找到之后被放到柜台上,最终我是从柜台上取走这个包裹的
- 那对于存储器来说也是一样,刚才CPU给他提供了一个它想要的数据的存放地址,那么主存储器里边的一些控制逻辑会根据这个位置找到它想要的数据
- 并把它想要的数据先写到MDR这个寄存器当中,最后CPU就可以通过数据线路从MDR中取走他想要的数据
- 主存储器和菜鸟驿站的这个模型是有很多相通的地方,但也有不一样的地方,对于菜鸟驿站来说,我们只能从他的货架上取走我们的包裹
- 而对于存储器来说CPU既可以从其中读出数据,同时也可以写入数据,写入数据的过程,其实和读入数据是很类似的
- CPU会指明它想要写入到哪个位置,想要写入的具体数据会被放到MDR当中, 最后CPU会通过控制总线告诉主存储器, 这次我想要执行的操作是写操作,而不是读操作
- 主存储器根据CPU发出的指令就可以往对应的位置写入CPU想要写的数据
存储体

- 我们要的二进制数据是存放在存储体当中的,并且是按地址来存储
- 就是说我们一整个存储体它会被分成一个一个的存储单元,每一个存储单元存放一串二进制代码
- 每一个单元里面存储的这一串二进制代码,我们就把它称为一个存储字,英文的话就是word
- 而每一个存储字包含多少个二进制位这个信息,我们把它称为存储字长,也就是每个存储单元里面可以放得下多少个二进制位
- 通常,每一个存储单元可以存放到二进制数都是8个比特的整数倍,也就是8bit或者16bit或者32bit或者64bit…,这是比较常见的一些存储字长
- 每一个这样的存储单元对应一个地址信息,地址是从0开始的,这个地址信息就是刚才我们所说的MAR里面应该指明的一个信息
- 如果要读取的是第2号的存储单元,那么CPU就应该往MAR这个寄存器里面写入2这个信息
- 最后还有一个概念叫做存储元,也就是用于存储二进制数据的电子元件,每个存储元可存1bit, 这样的电子元件其实是用电容的原理来制造的
- 电容可以用来存储电荷,因此我们可以用一个电容来存放一个二进制的比特位
- 由多个存储元件和相应的线路就构成了一个存储单元
- MAR是指明了我此次要访问哪一个存储单元,指明了存储单元的地址
- 所以MAR这个寄存器它的位数(有几个比特位),这个信息就直接的反映了我们的存储体里面到底有多少个存储单元
- 另一方面我们从存储单元里面取出来的数据是要放到MDR当中的,所以MDR它的二进制位数应该和存储单元是保持一致的,也就是要等于存储字长
- 比如:一个主存储体的MAR只有4个比特位,也就是这个存储体总共有 2 4 2^4 24 个存储单元,因为4个二进制位,最多只能表示 2 4 2^4 24 这么多个地址
- 同样的,如果MAR总共有16个比特位,就说明在这个主存储器中,一个字(word)的大小是16bit, 换一个角度说,
- 每一个存储单元可以存放16个二进制位,16个比特的信息
- 所谓一个字(word)的概念,这个和字节是容易混淆的
- 字节:1个字节(Byte) = 8bit, 也就是8个比特位; 简洁表示:1B = 1个字节,1b = 1个比特
- 字:一个字到底有多少bit取决于计算机硬件的结构和设计,一个字的大小 有可能是 8bit, 16bit, 32bit, 64bit …
- 生活中办理带宽,比如:100Mbps, 注意这里的b是小写的,表示每秒钟可以传递100M的bit位的速率
- 但是用一些工具,比如迅雷下载,一般是以B作为计量单位的,一般会显示 十几兆 M的速度
- 这并不是运营商的欺诈,而是换算单位不同,100 / 8 = 12.5 M, 而 100 是峰值,数据也是波动的
运算器
- 运算器:用于实现算术运算(如:加减乘除)、逻辑运算(如:与或非)
- 一个运算器最主要的部件,有这样的四个:ACC, MQ, ALU, X,如下图所示

- ACC(Accumulator): 累加器,用于存放算术运算和逻辑运算的操作数,或运算结果
- MQ(Multiple-Quotient Register): 乘商寄存器,在乘、除运算时,用于存放乘除操作数或运算结果
- X: 通用的操作数寄存器,可简称为通用寄存器(通用寄存器在运算器中可能会有多个),用于存放操作数
- ALU(Arithmetic and Logic Unit): 算术逻辑单元,是运算器的核心部件,通过内部复杂的电路实现算术运算、逻辑运算
- 前三者用于存放数据的,而且硬件构造并不复杂,而最后一个核心部件非常复杂,制造成本最高
- 总结下:有三个不可或缺的寄存器,还有一个核心部件ALU实现算术运算和逻辑运算
加 | 减 | 乘 | 除 | |
---|---|---|---|---|
ACC | 被加数、和 | 被减数、差 | 乘积高位 | 被除数、余数 |
MQ | 乘数、乘积低位 | 商 | ||
X | 加数 | 减数 | 被乘数 | 除数 |
控制器

- CU(Control Unit): 控制单元,分析指令,给出控制信号,是控制器中最核心部件
- IR(Instruction Register): 指令寄存器,存放当前执行的指令
- PC(Program Counter): 程序计数器,存放下一条指令地址,有自动加1的功能
- 计算机最主要的工作是执行代码,所谓的代码就是一条条指令,每完成一条指令可以分三个阶段
- 取指令: PC
- 分析指令:IR
- 执行指令:CU
- 备注:分析指令,也是CU来处理,但是这些指令存放在IR上
- 过程:
- 会根据PC程序计数器中记录的指令地址,从内存中取出当前指令
- 取出的指令会被存放到指令寄存器IR中
- CU就会分析这条指令并控制其他部件来配合完成指令的执行
- 通常:
- 前两个阶段被称为取指的过程
- 最后一个阶段被称为执行的过程
计算机的工作过程
-
下面是一段C语言的代码片段
int a = 2, b = 3, c = 1, y = 0; void main() { y = a * b + c; }
-
这一段代码是高级语言编写,事实上,我们的CPU不可能一次性完成这样的复合运算
-
他只能先进行乘法,然后再进行加法,分成这样的两大步骤,所以这段程序在经过底层编译之后,
-
可以把这个高级语言翻译成机器能读得懂的机器语言,同时把这段程序装入主存,如下图所示

- 0 ~ 4 对应 y=a*b+c 底层的机器指令 存放的地址
- 每条指令分为:操作码和地址码,一共16bit,被拆解成两部分
- 每个存储单元是16bit
- 5 ~ 8 对应 变量 存放的地址

- M: 主存中某存储单元
- ACC、MQ、X、MAR、MDR…: 相应寄存器
- M(MAR): 取存储单元中的数据
- (ACC)…: 取相应寄存器中的数据
- OP(IR): 取操作码
- Ad(IR): 取地址码
- CPU区分指令和数据的依据:指令周期的不同阶段
取数
- 我们所有的指令和数据都会存放在存储体中的
- 上述c语言程序第一条指令是存放在0号地址的, 在程序运行之前,PC会指向0的位置, 取出这条指令来执行,即:(PC) = 0, 指向第一条指令的存储地址
- PC存放的内容,会通过地址总线把它传送到MAR这个地址寄存器中,此时PC是0, 即:(PC) -> MAR, 导致 (MAR) = 0 备注:MAR寄存器的值变为了0
- 也就是说控制器向主存指明了我接下来要访问的是0号地址对应的数据, 同时,控制器会通过控制总线告诉主存储器进行读操作
- 接下来,主存储器会根据MAR记录的地址信息去存储体里面找出0号地址存储的二进制数据,把这些数据放入MDR数据寄存器当中, 即:M(MAR) -> MDR, 导致(MDR) = 000001 0000000101
- 现在CPU想要的数据已经被放到MDR中了,接下来取走这条指令数据,并存放在IR中,即:(MDR) -> IR, 导致(IR) = 000001 0000000101
- 接下来这条指令:000001 0000000101 中的前6个:000001,会被送到CU控制单元里面,CU会分析这个操作码, 000001 对应取数的指令
- 接下来将剩下的0000000101,这10bit对应的地址码执行的内存单元中的数据, 即5号地址位的 0000000000000010 取出,拿到原始数据2
- 即:OP(IR) -> CU, 指令的操作码送到CU, 指令的操作码送到CU, CU分析后得知,这是"取数"指令, Ad(IR) -> MAR, 指令的地址码送到MAR,导致(MAR) = 5
- 接下来主存储器根据MAR指明的地址,去存储体中找出5号单元的数据,并把这些数据放到MDR中,即:M(MAR) => MDR, 导致(MDR) = 0000000000000010 = 2
- 即:a = 2, 最后在控制单元指挥下,MDR中的数据会被传送到ACC累加寄存器当中, 即:(MDR) -> ACC, 导致(ACC) = 0000000000000010 = 2
- 到此为止,我们就完成了一个取数的指令, 变量a的值就会被传送到ACC寄存器中了
- 以上是一条机器语言描述的指令,以及指令的执行过程, 程序计数器PC有自动加1的功能,当取指令的动作完成之后,PC的值就会自动加1了,指明下一次需要执行的指令
- 第一次PC是0,取指令后自动加1变为了1,即:(PC) = 1, (ACC) = 2,之后取指令的过程和之前类似
- 需要注意乘法和存数,停机指令的区别,以下简述
乘法
- 上一条指令取值后PC自动+1,(PC) = 1; 执行后, (ACC) = 2
- (PC) -> MAR, 导致(MAR) = 1
- M(MAR) -> MDR, 导致(MDR) = 000100 00000000110
- (MDR) -> IR, 导致(IR) = 000100 00000000110
- OP(IR) -> CU, 指令的操作码送到CU, CU分析后得知,这是"乘法"指令
- 我们的程序是:y = ab + c, 现在ab的操作,而a之前已经在ACC中了,b的地址也已经读取到了
- Ad(IR) -> MAR, 指令的地址码送到MAR,导致(MAR) = 6 (这是b的地址)
- M(MAR) -> MDR, 导致(MDR) = 0000000000000011 = 3 (6号存储单元的数据,即b的值)
- (MDR) -> MQ, 导致(MQ) = 0000000000000011 = 3, 即:乘数被放到乘商寄存器MQ中
- (ACC) -> X, 导致(X) = 2,即:被乘数2被放入了X通用寄存器里
- 接下来,CU通过控制线告诉ALU进行乘法运算, ALU 会把 X 和 MQ 中的数据进行相乘,并将最后乘积存入ACC中
- (MQ) * (X) -> ACC, 由ALU实现乘法运算,导致(ACC) = 6, 如果乘积太大,ACC寄存器存储不下,则需要MQ辅助存储,MQ中会存储乘法运算结果的低位
- 这条指令取值后,(PC) = 2, 执行后,(ACC) = 6
加法
- (PC) -> MAR, 导致(MAR) = 2
- M(MAR) -> MDR, 导致(MDR) = 000011 0000000111
- (MDR) -> IR, 导致(IR) = 000011 0000000111
- OP(IR) -> CU, 指令的操作码送到CU, CU分析得知,这是加法指令
- Ad(IR) -> MAR, 指令的地址码送到MAR, 导致(MAR) = 7
- M(MAR) -> MDR, 导致(MDR) = 0000000000000001 = 1
- (MDR) -> X, 导致(X) = 0000000000000001 = 1
- (ACC) + (X) -> ACC, 导致(ACC) = 7, 由ALU实现加法运算
- 备注:取完指令后,PC会自增,(PC) = 3, 执行后,(ACC) = 7
存数
- (PC) -> MAR, 导致(MAR) = 3
- M(MAR) -> MDR, 导致(MDR) = 000010 0000001000
- (MDR) -> IR, 导致(IR) = 000010 0000001000
- OP(IR) -> CU, 指令的操作码送到CU, CU分析后得知,这是"存数"指令
- Ad(IR) -> MAR, 指令的地址码送到MAR, 导致(MAR) = 8
- (ACC) -> MDR, 导致(MDR) = 7
- (MDR) -> 地址为8的存储单元,导致y=7
- 此时PC自增,(PC) = 4
停机
- (PC) -> MDR, 导致(MDR) = 3
- M(MAR) -> MDR, 导致(MDR) = 000110 0000000000
- (MDR) -> IR, 导致(IR) = 000110 0000000000
- OP(IR) -> CU, 指令的操作码送到CU, CU分析后得知,这是"停机"指令
- 利用中断机制来通知操作系统终止该进程,接来下由操作系统接盘
总结
- 各硬件部件
- 主存
- 存储体:概念:存储元,存储单元,存储字,存储字长、地址
- MAR:地址寄存器,用于指明要读/写哪个存储单元,其位数反应存储单元数量
- MDR:数据寄存器,用于暂存要读/写的数据,其位数 = 存储字长
- 运算器
- ACC:了你按计数器,存放操作数,运算的结果
- MQ:乘商寄存器,进行乘、除法时用得到
- X:通用寄存器,存放操作数
- ALU:算术逻辑单元,用电烤炉实现各种算术运算,逻辑运算
- 控制器
- PC:程序计数器,存放下一条指令的地址
- IR:指令寄存器,存放当前执行的指令
- CU:控制单元,分析指令,给出控制信号
- 工作过程
- 初始:指令、数据存入主存,PC指向第一条指令
- 从主存中取指令放入IR, PC自动加1,CU分析指令,CU指挥其他部件执行指令
- 主存
- 备注:
- 现在的计算机通常把MAR,MDR集成在CPU内
- 冯诺依曼计算机的个特点:
- 计算机由五大部件组成
- 指令和数据以同等地位存于存储器,可按地址寻访
- 指令和数据用二进制表示
- 指令由操作码和地址码组成
- 存储程序
- 以运算器为中心(现在一般以存储器为中心)