# 冯诺依曼计算机的特点

\quad 1945 年,数学家冯诺依曼在研究 EDVAC\text{EDVAC} 机时提出了 “存储程序” 的概念。以此概念为基础的各类计算机称为冯诺依曼机。它的特点可归结如下:

  1. 计算机由运算器存储器控制器输入设备输出设备五大部件组成。
  2. 指令和数据以同等地位存放于存储器内,并可按地址寻访。
  3. 指令和数据均用二进制数表示。
  4. 指令由操作码和地址码组成,操作码用来表示操作的性质,地址码用来表示操作数在存储器中的位置。
  5. 具有存储程序。指令在存储器内按顺序存放。通常,指令是顺序执行的,在特定条件下,可根据运算结果或根据设定的条件改变执行顺序。
  6. 以运算器为中心,输入输出设备与存储器间的数据传送通过运算器完成。

# 计算机的硬件框图

\quad 典型的冯诺依曼计算机是以运算器为中心的,其硬件框图如图 11 所示。
图1
冯诺依曼计算机是以运算器为中心的,这是它的最大特定。就如图 11 所示,我们看到输入设备想输入数据得通过运算器储存在存储器中;输出设备想输出数据,从存储器通过运算器来输出。
\quad 我们可以看看上图中各部件的功能:

  1. 运算器用来完成算术运算和逻辑运算,并将运算的中间结果暂存在运算器内。
  2. 存储器用来存放数据和程序。
  3. 控制器用来控制、指挥程序和数据的输入、运行以及处理运算结果。
  4. 输入设备用来将人们熟悉的信息形式转换为机器能识别的信息形式,常见的有键盘、鼠标等。
  5. 输出设备可将机器运算结果转换为人们熟悉的信息形式,如打印机输出、显示器输出等。

\quad 冯诺依曼计算机的结构存在着两种问题:一种是以运算器为中心,导致运算器成为系统的瓶颈;另一种是结构框图 “看起来” 比较乱,不具有层次性。于是我们便对这种结构进行了改进。
\quad 改进就是:以存储器为中心。把原来把运算器为中心的机器,改为以存储器为中心,实现了输入、输出设备直接地进行信息交换。如下图 22 所示。
图2
上图中,双箭头线表示数据线,用于数据的传输:输入设备可以直接将数据存入存储器中;运算器可以直接从存储器中提前数据,也可以将运算结果保存到存储器当中。

\quad 此外,由于运算器和控制器在逻辑关系和电路结构上联系十分紧密,尤其在大规模集成电路制作工艺出现后,这两个部件往往集成在同一芯片上,因此,通常将它们合起来统称为中央处理器 (Central Processing Unit),又称为 CPU\text{CPU}。存储器又分为主存辅存,其中主存与 CPU\text{CPU} 一起构成了主机。而我们又把输入设备与输出设备简称为 I/O\text{I/O} 设备,又可称为外部设备。
图3

这样,现代计算机便可认为由三大部分组成:CPU\text{CPU}I/O\text{I/O} 设备以及主存储器,其组成框图如图 44 所示,可以看出它更加具有层次化。
图4

# 计算机编制解题程序

\quad 写程序,写程序,写程序...... 什么是程序?程序是适合于计算机运算的全部步骤,编制一个解题程序就是将运算步骤用一一对应的机器指令来描述。下面,我们来举一个经典的例子:假设 a,b,c,xa,b,c,x 都以及储存在存储器中了,计算 ax2+bx+cax^2+bx+c 可分解为以下步骤。

  1. xx 从存储器取至运算器。
  2. 乘以 xx,得到 x2x^2,存于运算器中。
  3. 再乘以 aa,得 ax2ax^2,存于运算器中。
  4. ax2ax^2 送至存储器中。
  5. bb 至运算器中。
  6. 乘以 xx,得 bxbx,存于运算器中。
  7. ax2ax^2 从存储器中取出与 bxbx 相加,得 ax2+bxax^2+bx,存于运算器中。
  8. 再取 ccax2+bxax^2+bx 相加,得 ax2+bx+cax^2+bx+c,存于运算器中。

注,运算器内部拥有寄存器,相比存储器的主存,寄存器是小容量的存储设备,但它可以提供极快的数据访问速度,因此通常用来存储执行指令时需要快速访问的数据和中间计算结果。所以不用对 “存于运算器” 感到意外噢!
\quad 上面的例子中,编制这个解题程序,不包括停机、输出打印共需八步。但若我们寻求到好的算法,则可以简化步骤。例如将上式改写为 (ax+b)x+c(ax+b)x+c,就可以简化为五部:

  1. xx 从存储器取至运算器。
  2. 再乘以 aa,得 axax,存于运算器中。
  3. bb,得 ax+bax+b,存于运算器中。
  4. 乘以 xx,得到 (ax+b)x(ax+b)x,存于运算器中。
  5. cc,得 (ax+b)x+c(ax+b)x+c,存于运算器中。

将上述运算步骤写成计算机一一对应的机器指令,就完成了运算程序的编写。

# 操作码和地址码

\quad 计算机的一个指令用二进制的数来表示。比如说有一种机器的指令码字长 1616 位,其中操作码占 66 位,地址码占 1010 位,如下图所示。

图5

其中,操作码表示机器所执行的各种操作,如取数、存数、加、减、乘、除、停机、打印等。地址码表示参加运算的数在存储器内的位置。机器指令的操作码和地址码都采用了 0011 代码的组合来表示。
\quad11 给出了某机器操作码与对应的操作关系。
表1
注:ACC 就是累加器的缩写。

\quad 上一节的计算 ax2+bx+cax^2+bx+c 的例子中,我们说过 x,a,b,cx,a,b,c 是事先存于存储器中了。我们按上一节的算法,编写了一份运算程序的清单,如表 22 所示。
表2
从上表中,我们应该可以体会到 “指令与数据以同等地位保存在存储器中” 这句话的含义了吧!

# 计算机的五大组成部分

# 主存储器

\quad 主存储器又称为主存或内存,其包括了存储体 M、各种逻辑部件以及控制电路等。

\quad 存储体由许多存储单元组成,每个存储单元又包含若干个存储元,每个存储元可以存放一位 “0” 或 “1” 的二进制代码。可见,一个存储单元可以存储一串二进制代码,这串二进制代码可以是某个指令码,也可以是某个存储单元的地址码,又或许是某个 “数”,我们称这串二进制代码为一个存储字,其位数称为存储字长
\quad 如果把一个存储体看作一栋大楼,那么每个存储单元可以看作大楼中的每个房间,每个存储元可以看作每个房间中的一张床位,“0” 或 “1” 表示床位是否有人。床位数相当于存储字长。而每一个房间都需要一个门牌号,这就是存储单元的地址号。主存的工作方式就是按存储单元的地址号来实现对存储字各位的写入、读出

\quad 为了能够实现按地址访问的方式,主存中还需要配置两个寄存器 MAR 和 MDR。MAR(Memory Address Register)是存储器地址寄存器,它用于存放欲访问的存储单元的地址号,其位数就对应着主存的存储单元个数(例如,MAR 有 10 位,则一共有 210=10242^{10}=1024 个存储单元)。MDR(Memory Data Register)是存储器数据寄存器,用于存放从某个存储单元取出的代码或准备送往某存储单元的代码,其位数与存储字长相等。
\quad MAR 与 MDR 在计算机中的作用可以描述为是主存和 CPU 之间交付的一共中转站,CPU 和主存之间进行数据 / 地址的交互时,都需要 MAR 或 MDR 进行中转。我们可以把这个中转大致描述为一下两种场景:

  1. CPU 从主存中读取指令 / 数据:CPU 将要读取的指令通过地址总线送至 MAR,MAR 将地址交付给主存,主存根据地址找出对应的指令 / 数据,将数据交付给 MDR,最后 MDR 将数据交付给 CPU。
  2. CPU 将数据写入主存:CPU 将数据写入主存时,首先需要将写入对应主存的地址送至 MAR,MAR 会将地址交付给主存,同时 CPU 将数据送至 MDR,MAR 再将数据交付给主存,主存根据地址将数据写入对应的存储单元。

\quad 目前,随着硬件技术的发展,主存都制成大规模集成电路的芯片,而将 MAR 和 MDR 集成在 CPU 芯片中。

图6图7

# 运算器

\quad 运算器大致可以看作由四部分组成:ACC(Accumulate Register)中文又叫做累加寄存器;MQ(Multiple—Quotient Register),中文叫做乘商寄存器;X,中文叫做操作数寄存器;ALU (Arithmetic and Logical Unit),运算器的核心部件,算术逻辑单元,通过内部电路实现算数运算和逻辑运算。
\quad 3 个寄存器在完成不同运算时,所存放的操作数类别也各有不同。表 3 列出了寄存器存放不同类别操作数的情况。

表3

\quad 不同机器的运算器结构是不同的。我们以图 8 这种运算器结构来简要分析一下加、减、乘、除四则运算的操作过程。
\quad 我们设 M 表示存储器的任一地址号,[M] 表示相应的存储内容;X 表示为 X 寄存器,[X] 表示 X 寄存器中的内容;同理有 ACC、[ACC]、MQ、[MQ]。并且我们假设 ACC 中已经存有前一时刻的运算结果。

  • 加法操作过程为:

[M]X[ACC]+[X]ACC\begin{aligned} [\text{M}] &\longrightarrow \text{X} \\ [\text{ACC}] + [\text{X}] &\longrightarrow \text{ACC} \end{aligned}

即我们将原本就已经存在的 [ACC] 看作被加数,先从主存的一个存储单元 M 中取加数 [M] 送至运算器的 X 寄存器中,然后运用 ALU 将被加数 [ACC] 与加数 [X] 相加,结果保留在 ACC 中。

  • 减法的操作与加法类似:

[M]X[ACC][X]ACC\begin{aligned} [\text{M}] &\longrightarrow \text{X} \\ [\text{ACC}] - [\text{X}] &\longrightarrow \text{ACC} \end{aligned}

  • 乘法操作过程为:

[M]MQ[ACC]X0ACC[X]×[MQ]ACC//MQ\begin{aligned} [\text{M}] &\longrightarrow \text{MQ} \\ [\text{ACC}] &\longrightarrow \text{X} \\ 0 &\longrightarrow \text{ACC} \\ [\text{X}] \times [\text{MQ}] &\longrightarrow \text{ACC} // \text{MQ} \end{aligned}

我们将原本存在的 [ACC] 看作被乘数,先取除 M 中的 [M] 作为乘数送至乘商寄存器 MQ 中,再把被乘数 [ACC] 送至 X 寄存器。(前两个步骤可以调换顺序或同步进行,这得看控制器如何协调)。然后我们将 ACC 清 “0”。之后利用 ALU 将 [X] 与 [MQ] 相乘,结果(积)的高位保留在 ACC 中,低位保留在 MQ 中。
碎碎念:那什么是乘积的地位,什么是乘积的高位?为什么要把结果分开存储?这里没怎么看懂。

  • 除法操作过程:

[M]X[ACC]÷[X]MQ\begin{aligned} [\text{M}] &\longrightarrow \text{X} \\ [\text{ACC}] \div [\text{X}] &\longrightarrow \text{MQ} \end{aligned}

除法的操作如上,结果(商)暂留于 MQ,余数 R 则留于 ACC 中。

碎碎念:乘法与除法这块没看懂。在计算机组成原理的书籍中,后面会有专门一章将计算机运算方法的。但我大概率不会学到那了。不过没关系,注意目的也不是把所有细节学懂,对计算机有一个初步的概念就好啦!