1 CPU 内部逻辑结构
之前的文章《揭秘代码是如何变成机器码的》,其中说到,如果从软件的角度来讲,CPU 就是一个执行各种计算机指令(Instruction Code)的逻辑机器。
那么这个逻辑机器内部是什么样的?又是如何执行指令的呢?逻辑上,我们可以认为,CPU 其实就是由一堆寄存器组成的。如果要和硬件电路做一下对应,CPU 是一个庞大而复杂的电路,寄存器就是由多个触发器(Flip-Flop)或者锁存器(Latches)组成的简单电路。
2 寄存器
一个 CPU 里面会有很多种不同功能的寄存器,例如通用寄存器、PC 寄存器、指令寄存器、标志寄存器和其他寄存器等。。
- 通用寄存器:所谓通用,即这些寄存器 CPU 没有特殊的用途,交给应用程序“随意”使用。通用寄存器既可以存放数据,也可以存放地址。
- PC寄存器:也叫指令地址寄存器,用来存放下一条需要执行的计算机指令的内存地址。
- 指令寄存器:存放当前正在执行的指令。
- 标志寄存器:用来记录了CPU执行指令过程中的一系列状态,例如ZF是零标志,CF是进位标志。
- 其他寄存器:比如整数寄存器、浮点数寄存器、向量寄存器和地址寄存器等
3 计算机指令执行过程
当了解了寄存器之后,你也大概能猜到 CPU 到底是如何执行计算机指令的,下面寄存器视角的计算机指令执行流程:
- 取指;从 PC 寄存器里找到对应的指令地址,根据指令地址从内存里把具体的指令,加载到指令寄存器中,然后把 PC 寄存器自增,以便继续执行下一条指令。
- 译码;识别指令的类型,对取回来的指令进行拆分和解释,识别出不同的指令类别和各种获取操作数的方法,得到具体要操作哪些寄存器、数据或者内存地址。
- 执行;将数据送给计算单元或者控制单元进行具体的计算和跳转。
- 访存;有些指令可能需要从主存加载数据。例如有些需要得到操作数在主存中的地址,并从主存中读取操作数用于计算。
- 写回;有些指令对寄存器或者主存状态有影响,需要将结果写入这些受影响的寄存器或者主存。
CPU 执行指令,其实是由计算机的不同组件协作完成的。
取指令的过程,是控制器通过 PC 寄存器和指令寄存器将指令从存储器中取出来的。
指令的解码过程,也是由控制器进行的。
执行指令阶段,无论是进行算术操作,还是进行数据传输,都是由运算器处理的。不过,如果只是一个简单的无条件地址跳转,这个过程是在控制器里面完成,不需要用到运算器。
访存和写回操作,都是由控制器控制完成的。
4 时钟周期、指令周期、CPU 周期
前面我们了解到 CPU 其实是由寄存器和锁存器组成,执行计算机指令的过程是“取指、译码、执行、访存、写回”,那么这个执行过程是如何做到“自动”运行的呢?这个过程中有时需要保存中间状态,这个中间状态又是怎么样保持的呢?这其中的时序协调问题又是怎么做到的呢?
其实这是依靠时序逻辑电路实现的。这个属于数字电路方面的知识,虽然学过,但是早已经还给老师了。作为计算机方面的入门,我们最需要关心的是的三种周期,对于后续了解流水线原理是有帮助的。
时钟周期是处理器执行动作的最小时间单位。谈到 CPU,我们经常会提到主频,主频越高,速度越快。CPU 主频通常以 GHz 为单位,表示的是 CPU 中计时单元每秒震荡的次数,时钟周期就是每次震荡消耗的时间,所以有时也称为震荡周期。例如,如果计算机的时钟频率为 1 GHz(1,000,000,000 次/秒),那么每个时钟周期的持续时间就是 1 纳秒(1/1,000,000,000 秒)。
指令周期是计算机处理器执行一条指令的全过程,包括从内存中读取指令、解码指令、执行指令等几个步骤。一个指令周期通常由几个机器周期组成,具体取决于指令的复杂性和处理器的设计。
CPU 内部的操作速度很快,但是访问内存的速度却要慢很多。每一条指令都需要从内存里面加载而来,所以我们一般把从内存里面读取一条指令的最短时间,称为 CPU 周期(机器周期)。
5 建立数据通路
当知道了计算机指令执行过程,也知道了时钟信号如何实现的,时钟信号其实是实现了“自动”执行,现在来看整个过程中各个部件是如何协同工作的。
-
程序计数器(PC 寄存器)指向指令所在的存储单元 。
-
其后连接一个译码器,译码器连着 D 触发器组成的内存。
-
自动计数器会随着时钟主频不断自增,从译码器当中,找到对应的计数器所表示的内存地址,然后读取出里面的 CPU 指令。
-
读取出来的 CPU 指令会通过 CPU 时钟的控制,写入到一个由 D 触发器组成的寄存器,也就是指令寄存器当中。
-
指令寄存器后面再跟一个译码器,用来把指令解析成操作码和对应的操作数。
-
当拿到对应的操作码和操作数,对应的输出线路就要连接 ALU,开始进行各种算术和逻辑运算。对应的计算结果,则会再写回到 D 触发器组成的寄存器或者内存当中。