| 项目 | 值 |
|---|---|
| 取指 | PC → MAR → 主存 → MDR → IR,同时 PC + 1 |
| 译码 | 分析操作码 OP(IR) 和操作数地址 Ad(IR) |
| 执行 | 取操作数 → 运算 → 存结果 |
指令周期 = 取指周期 + 执行周期
更细的分解:
指令周期 = 取指 + 译码 + 执行 + 访存 + 写回 + 中断检查
| 层次 | 含义 | 关系 |
|---|---|---|
| 时钟周期(节拍 / T) | CPU 的最小时间单位,一次基本微操作 | 最小 |
| 机器周期(CPU 周期) | 完成一个基本工作阶段(如取指) | = 若干时钟周期 |
| 指令周期 | 完整执行一条指令 | = 若干机器周期 |
指令周期(最长)
├── 取指周期 (必有)
├── 间址周期 (仅间接寻址时有)
├── 执行周期 (必有)
└── 中断周期 (仅有中断请求且允许响应时有)
FE / IND / EX / INT 四个触发器区分当前处于哪个工作周期,控制器据此发出不同的微操作命令。1. PC → MAR // 将 PC 的值送 MAR
2. MAR → 地址总线 // 地址送地址总线
3. CU 发出读命令 // 控制器发读信号
4. 主存 → 数据总线 → MDR // 内存数据送 MDR
5. MDR → IR // 指令送 IR
6. PC ← PC + 指令长度 // PC 自动更新
7. OP(IR) → ID // 操作码送译码器
| 节拍 | 微操作 |
|---|---|
| T0 | PC → MAR |
| T1 | MAR → 地址总线,CU 发读命令 |
| T2 | 等待主存响应 |
| T3 | MDR ← 数据总线 |
| T4 | MDR → IR |
| T5 | PC ← PC + len |
| T6 | OP(IR) → 译码器 |
触发条件:指令使用间接寻址,需先从主存取出有效地址 EA。
1. MAR ← Ad(IR) // 形式地址送 MAR
2. CU 发出读命令
3. MDR ← M[MAR] // 从主存取出有效地址
4. Ad(IR) ← MDR // 用 EA 更新指令的地址码
ADD R1, [addr]1. MAR ← Ad(IR) // 取地址
2. MDR ← M[MAR] // 取操作数
3. R1 ← R1 + MDR // ALU 做加法
4. 更新标志位(ZF / CF / OF / SF)
STO R1, [addr]1. MAR ← Ad(IR) // 取地址
2. MDR ← R1 // 取数据
3. M[MAR] ← MDR // 写入主存
JMP addr1. PC ← Ad(IR) // 直接改写 PC
BEQ R1, R2, offset1. if (R1 == R2) then PC ← PC + offset
// 需 ALU 做比较(相减)并根据标志位判断
响应条件(三者必须同时满足):
1. 关中断
2. 保存断点:PC(返回地址)压栈或存入特定单元
3. 保存现场:PSW 和通用寄存器压栈
4. 识别中断源:确定中断类型 → 取中断服务程序入口
5. 转入服务程序:PC ← 中断服务程序入口地址
把指令执行拆成多个阶段,各阶段使用不同的硬件部件,因而可以让多条指令在不同阶段上重叠推进。
| 方式 | 时间轴(每格 1 个 $\Delta t$) |
|---|---|
| 非流水线 | I1: 取指 译码 执行 写回,I2 必须等 I1 全部完成后才开始 |
| 流水线 | I1 进入译码时 I2 即可开始取指,每拍流出一条指令 |
设有 $n$ 条指令、$k$ 级流水线,每级耗时 $\Delta t$:
| 指令类型 | 取指 | 译码 | 执行 | 访存 | 写回 | 总周期 |
|---|---|---|---|---|---|---|
| 寄存器运算 | 1 | 1 | 1 | 0 | 1 | 4 |
| Load(取数) | 1 | 1 | 1 | 1 | 1 | 5 |
| Store(存数) | 1 | 1 | 1 | 1 | 0 | 4 |
| 分支 | 1 | 1 | 1 | 0 | 0 | 3 |
ADD R1,[addr])与总线结构,按节拍写出取指 / 执行周期的微操作。PC ← PC + len)与取指的访存操作互不干扰,因此实际机器常把它与 T1/T2 并行完成以缩短取指周期。↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。