指令周期(Instruction Cycle)
指令种类
-
- Fetch(取得指令)
- 也就是从PC寄存器里找到对应的指令地址,根据指令地址从内存里把具体的指令,加载到指令寄存器中
- 然后把PC寄存器自增,好在未来执行下一条指令
-
- Decode(指令译码)
- 也就是根据指令寄存器里面的指令,解析成要进行什么样的操作,是R、I、J中哪一种指令
- 具体要操作哪些寄存器、数据或者内存地址
-
- Execute(执行指令)
- 也就是实际运行对应的R、I、J这些特定的指令,进行算术逻辑操作、数据传输或者直接的地址跳转
-
- 重复进行 1 ~ 3的步骤
- 这样的步骤,其实就是一个永不停歇的"Fetch - Decode - Execute"的循环,我们把这个循环称之为
指令周期(Instruction Cycle)
指令的布署
-
在上图的指令循环过程中,不同部分其实是由计算机中的不同组建完成的
-
在取指令(Fetch)的阶段,指令是放在
存储器
里的 -
实际上,通过PC寄存器和指令寄存器取出指令的过程,是由
控制器(Control Unit)
操作的,指令的解码过程,也是由控制器
进行的 -
一旦到了执行指令阶段,无论是进行算术操作、逻辑操作的R型指令,还是进行数据传输、条件分支I型指令,都是由
算术逻辑单元(ALU)
操作,也就是由运算器
处理的 -
不过,如果是一个简单的无条件跳转,那么我们可以直接在
控制器
里面完成,不需要用到运算器
周期类型
- Machine Cycle(机器周期、CPU周期)
- CPU内部的操作速度很快,但是访问内存的速度却要慢很多
- 每一条指令都需要从内存里面加载出来,所以一般把内存里面读取一条指令的最短时间,称为
CPU周期
- Clock Cycle(时钟周期、机器主频)
- 一个CPU周期,通常会由几个时钟周期累积起来的
- 一个CPU周期的时间,就是这几个Clock Cycle的总和
指令周期、机器周期、时钟周期的关系
-
对于一个指令周期来说,取出一条指令,然后执行它,至少需要两个CPU周期
-
取出指令至少需要一个CPU周期,执行至少也需要CPU周期,复杂的指令则需要更多的CPU周期
-
所以,我们说一个指令周期,包含多个CPU周期,而一个CPU周期包含多个时钟周期
建立数据通路
数据通路的组成(处理器单元)
- 操作元件
- 组合逻辑元件(Combinational Element),其实就是我们的ALU
- 在前面讲ALU的过程中可以看到,它们的功能就是在特定的输入下,根据下面的组合电路的逻辑,生成特定的输出
- 存储元件
- 也叫状态元件(State Element)
- 比如我们在计算过程中需要用到的寄存器,无论是通用寄存器还是状态寄存器,其实都是存储元件
- 通过数据总线的方式,把它们连接起来,就可以完成数据的存储、处理和传输了,这就是所谓的
建立数据通路
控制器
- 它的逻辑就没那么复杂,可以把他看成只是机械地重复"Fetch - Decode - Execute" 循环中的前两个步骤,然后把最后一个步骤,通过控制器产生的控制信号,交给ALU去处理
- 具体逻辑
-
一方面,所有CPU支持的指令,都会在控制器里面,被解析成不同的输出信号
-
之前说过,现在的Intel CPU 支持 2000 个以上的指令,意味着,控制器输出的控制信号,至少有2000种不同的组合
-
运算器里的ALU和各种组合逻辑电路,可以认为是一个固定功能的电路
-
控制器"翻译"出来的,就是不同的控制信号,这些控制信号,告诉ALU去做不同的计算
-
可以说正是控制器的存在,让我们可以“编程”来实现功能,能让我们的“存储程序型计算机”名副其实
CPU所需要的硬件电路
- 首先,自然是之前已经讲解过的ALU了,它实际就是一个没有状态,根据输入计算输出结果的第一个电路
- 第二,需要有一个能够进行状态读写的电路元件,也就是寄存器
- 需要有一个电路,能够存储到上一次的计算结果
- 这个计算结果并不一定要立刻拿到电路的下游去使用,但是可以在需要的时候拿出来用
- 常见的能够进行状态读写的电路,就有锁存器(Latch),以及D触发器(Data / Delay Flip-flop)电路
- 第三,需要有一个"自动"的电路,按照固定的周期,不停实现PC寄存器自增,自动地去执行"Fetch - Decode - Execute"
- 程序执行,并不是靠人去拨动开关执行指令,希望有一个"自动"的电路,不停去一条条执行指令
- 看似写了各种复杂的高级程序进行各种函数调用、条件跳转,其实只是修改PC寄存器里面的地址
- PC寄存器里面的地址一修改,计算机就可以加载一条指令新指令,往下运行
- 实际上,PC寄存器还有一个名字,就叫做程序计数器,顾名思义,就是随着时间变化,不断去数数
- 数的数字变大了,就去执行一条新指令
- 所以,需要的就是一个自动数数的电路
- 第四, 需要有一个"译码"的电路
- 无论是对于指令进行decode,还是对于拿到内存地址去获取对应的数据或者指令
- 都需要通过一个电路找到对应的数据,这个对应的自然就是"译码器"的电路