CPU内部:指令执行周期完整指南及数据如何从 RAM 中检索
Source: Dev.to
什么是 CPU 执行周期?
CPU(中央处理单元)使用一个称为 指令周期 或 取指‑译码‑执行(FDE) 周期的重复循环来处理指令。每条指令——无论是 ADD、MOV、LOAD、函数调用还是分支——都要经过这个周期。
三个主要阶段是:
- 取指(Fetch) – 从内存(RAM 或缓存)获取指令。
- 译码(Decode) – 理解指令的含义。
- 执行(Execute) – 执行操作(算术逻辑单元运算、内存访问、分支等)。
该循环每秒重复数十亿次。
CPU 架构概览
寄存器
CPU 内部极其快速的存储单元:
- PC(程序计数器) – 保存下一条指令的地址。
- IR(指令寄存器) – 保存正在译码/执行的指令。
- MAR(内存地址寄存器) – 保存内存地址。
- MDR(内存数据寄存器) – 保存正在从/向内存传输的数据。
- 通用寄存器 – AX、BX、RAX、RBX 等,取决于具体架构。
ALU(算术逻辑单元)
执行算术(加、减、乘)和逻辑(AND、OR、XOR)运算。
控制单元
指挥整个执行周期,协调取指、译码和执行。
缓存
非常快速的内存层级(L1、L2、L3),加速指令和数据的访问。
RAM(主存)
程序运行时指令和数据所在的地方。
指令周期逐步指南
步骤 1:取指
- PC → MAR – 将程序计数器的地址复制到内存地址寄存器。
- CPU 请求内存读取 – 地址被放到地址总线上。
- 内存返回指令 → MDR – 来自内存的数据进入内存数据寄存器。
- MDR → IR – 将取到的指令放入指令寄存器。
- PC 增加 –
PC = PC + 指令长度(通常是 +1、+4 等)。
此时 CPU 已经装载了指令,准备进行译码。
步骤 2:译码
控制单元 解释指令:
- 操作码(Opcode) – 表示的操作(加、移动、跳转)。
- 操作数(Operands) – 寄存器编号、内存地址、常数。
- 寻址方式 – 直接、间接、立即、索引。
此时还没有实际的数据处理,只是解释指令。
步骤 3:执行
CPU 执行动作,形式多样:
- 算术/逻辑运算 – ALU 完成运算,结果存入寄存器。
- 内存读取(LOAD)
- 计算有效地址。
- 将地址放入 MAR。
- 控制单元向内存发送 读取请求。
- 数据经数据总线进入 MDR。
- MDR → 目标寄存器。
- 内存写入(STORE) – 数据放入 MDR,地址放入 MAR,然后向内存发出写入信号。
- 分支 – 若条件为真,PC 更新为新地址;否则 PC 正常递增。
- I/O – 控制信号激活 I/O 控制器。
执行完毕后,周期重新从下一条指令开始。
CPU 实际从 RAM 获取数据的过程
步骤 1:缓存检查
CPU 首先在缓存层级(L1 → L2 → L3)中查找。
- 缓存命中 – 数据瞬间读取(纳秒级)。
- 缓存未命中 – 必须从 RAM 读取,速度较慢。
步骤 2:向 RAM 发送地址
地址通过 MAR 放到 地址总线 上。
步骤 3:RAM 响应
RAM 将请求的数据放到 数据总线 上。
步骤 4:数据进入 MDR
CPU 将数据捕获到内存数据寄存器。
步骤 5:传输到目标寄存器
示例汇编:
LOAD R1, [0x5000]
最后一步是 MDR → R1。
综合示例
ADD R1, [0x2000]
- 取指 – 从 PC 指向的地址取出指令。
- 译码 – 确认操作码
ADD与操作数(寄存器R1+ 内存位置0x2000)。 - 执行
- 计算有效地址
0x2000。 MAR = 0x2000。- RAM → MDR(读取内存)。
- ALU 将
R1与MDR相加。 - 将结果存回
R1。
- 计算有效地址
所有这些都在几个 CPU 时钟周期内完成。
流水线与并行(现代 CPU)
现代 CPU 通过以下技术提升吞吐量:
- 指令流水线 – 为多条指令的取指、译码、执行阶段交叉进行。
- 超标量执行 – 每个时钟周期发射多条指令。
- 乱序执行 – 重新排序指令以避免停顿。
- 分支预测 – 预测分支结果,以保持流水线满载。
这些优化使得每秒能够完成数十亿次操作。
小结
取指: PC → MAR → Memory → MDR → IR → PC++
译码: 控制单元解释操作码和操作数。
执行:
- ALU 运算
- 内存加载/存储
- 分支跳转
- I/O 操作
内存访问: 必经缓存 → (可能的)RAM → MDR → 寄存器。
理解这一周期可以让你深入了解代码在硬件层面的运行方式,对系统设计、汇编编程、编译器构建以及性能调优都至关重要。