--- title: "07-输入输出系统" created: 2026-08-29 tags: - 基础与理论 - 计算机组成原理 - "408" --- # 07 输入输出系统 > 📚 本文是 [[00-计算机组成原理总览|计算机组成原理]] 的第 7 篇,相关系列见 [[00-基础与理论|基础与理论]]。 [[01-计算机硬件速览|硬件速览]]里埋了两个伏笔:"键盘按一下,CPU 怎么知道?"(中断)和"搬大块数据还要劳烦 CPU 吗?"(DMA)。本章一次回收——这也是计组的收官篇:**CPU 和外设的三种相处方式**,从"死等"到"有事叫我"到"快递员直接送货"。 OS 视角的 I/O 软件栈(缓冲、驱动、设备分配)在 [[08-IO管理|I/O 管理]],本篇聚焦**硬件层机制**。 ## 一、接口与端口:CPU 怎么"摸到"设备 外设通过**接口(I/O Controller)**挂到总线,接口里有一排**寄存器**,即**端口(port)**:数据端口、状态端口、控制端口。 CPU 访问端口有两种编址: | 维度 | 统一编址(存储器映射 MMIO) | 独立编址(专用 I/O 指令) | |---|---|---| | 地址空间 | 端口占用**主存地址空间**的一段 | 端口独立于主存,另有小地址空间 | | 访问方式 | 普通访存指令(`mov` 直接读写设备) | 专门指令(x86 的 `IN/OUT`) | | 优点 | 指令丰富(所有访存指令都能操作设备)、无需额外控制线 | 地址空间不占主存、指令短、**程序意图清晰**(看到 IN/OUT 就知道在摸设备) | | 缺点 | 主存空间被"吃"一块;地址译码要区分内存和设备 | 需专门的 I/O 指令和控制线(多一根 IO/M̅ 信号) | | 代表 | ARM、RISC-V(MMIO 为主) | x86(同时支持两种) | 💡 GPU 显存([[04-显卡与GPU|显卡]])就是 MMIO 的活例子:`cudaMalloc` 返回的"显存指针",其实是主存地址空间里映射的一段——CPU 用普通访存指令就能摸到它。 ## 二、程序查询方式:最笨也最直白 ``` loop: 读状态端口 → 忙? 忙 → 跳回 loop 死等 闲 → 读/写数据端口 ``` - CPU **100% 轮询等待**,设备慢时全在空转 - 优点:接口简单、无额外硬件 - ⚠️ 效率极低——"CPU 等一行字符输入"就是这种模式的绝罚。面试里"忙等待(busy waiting)"的反面教材 ## 三、中断方式:有事叫我 ### 全流程(408 必背) 设备准备好 → 接口发**中断请求**(INTR 线)→ CPU 每条指令执行结束前查一次请求 → 允许且开中断则**响应**: 1. **关中断**(保护现场期间不再被打断) 2. **保存断点**:PC、PSW 压栈(有的硬件自动存,有的靠中断程序) 3. 引出中断服务程序:送**中断向量**(中断类型号 × 向量长度 → 向量表找入口),PC ← 服务程序入口 4. **保存现场**:通用寄存器压栈(软件干) 5. 执行**中断服务程序**本体(如从键盘缓冲区取字符) 6. **恢复现场**、**开中断**、**中断返回**(IRET:弹回断点) ⚠️ 1、2 步是**中断隐指令**——由硬件自动完成,不在任何指令集里,却真实存在。408 选择题爱考"哪一步属于隐指令":**关中断、保存断点、引出服务程序**这三件。 ### 中断分类一张图 ``` 中断(CPU 外部事件,异步) ├── 外中断(狭义的"中断") │ ├── 可屏蔽(INTR 线:键盘、打印机…PSW 的 IF 位可挡) │ └── 不可屏蔽(NMI 线:掉电、内存校验错…必须响应) └── 内中断(异常,CPU 执行指令时自己产生的,同步) ├── 故障 Fault(缺页、除 0——可修复,修复后重执行) ├── 自陷 Trap(系统调用、断点——**故意**的,[[01-操作系统概述|OS 概述]]的用户态入口) └── 终止 Abort(硬件错误——程序已救不了) ``` ⚠️ 核心区分:**异常(内中断)与当前指令同步,中断(外中断)与指令流异步**。缺页是异常不是中断——408 最爱出这道题。 ### 中断嵌套与屏蔽字 - 运行服务程序时又来了更急的请求 → **中断嵌套**:高优先级打断低优先级(条件:开中断状态下响应) - **屏蔽字技术**:每个中断源有一个屏蔽字,1 = 屏蔽(不许打断我)。把"自己 + 比自己低的"都置 1,就实现了**动态调整优先级** - **手算例题**:中断 A~D,响应优先级 A>B>C>D。若想让处理优先级变成 B>D>A>C,问各屏蔽字? - 规则:处理优先级高的,屏蔽"自己及所有处理优先级比自己低的"(1=屏蔽),不屏蔽比自己高的(0=放行) - B 最高:屏蔽 B、D、A、C → 1111 - D 次之:屏蔽 D、A、C,放行 B → 0111(按 B,D,A,C 位序) - A 再次:屏蔽 A、C,放行 B、D → 0011 - C 最低:只屏蔽自己 → 0001 - ⚠️ **响应优先级**(谁先被 CPU 看)由硬件排队器固定;**处理优先级**(谁能打断谁)由屏蔽字软件设——两套体系别混 ### 多重中断 vs 单重中断 单重中断:服务期间关中断,拒绝一切打扰;多重中断:服务期间开中断,允许更高级的插队。现代 OS 全是多重。 ## 四、DMA 方式:大块数据别劳烦 CPU 中断解决了"有事叫我",但**一字一中断**搬运 1MB 数据 = 100 万次中断——还是太亏。**DMA(Direct Memory Access)**让 DMA 控制器直接掌管总线,在**设备 ↔ 主存**之间整块搬运,CPU 只在开头出力。 ### DMA 的三种传送方式(争总线的方式) | 方式 | 怎么用总线 | 特点 | |---|---|---| | 停止 CPU 访存 | DMA 传输期间 CPU 完全让路 | 控制最简单;CPU 有一段"纯空窗" | | **周期挪用(周期窃取)** | DMA 一个周期一个周期地"偷"总线 | **最常用**;CPU 与 DMA 交替,DMA 优先 | | 交替访问 | 时间上轮流,各走各拍 | 需要总线周期比存储周期长一倍,硬件复杂 | ### DMA 流程(写盘为例) 1. **预处理**(CPU 干):设置 DMA 控制器的传送参数——主存起始地址、设备地址、**传送字数**,然后启动设备,CPU 转去干别的 2. **数据传送**(DMA 干):块级搬运,需要总线就申请(周期挪用),完全不经过 CPU 寄存器 3. **后处理**(CPU 干):传完后 DMA 发**中断**,CPU 校验数据、决定后续——⚠️ **DMA 结束仍要一次中断**,只是不再"一字一中断" ### DMA vs 中断——必背对比表 | 维度 | 中断方式 | DMA 方式 | |---|---|---| | 数据流向 | 设备 → CPU 寄存器 → 主存(**过路 CPU**) | 设备 ↔ 主存(**绕开 CPU**) | | 打断时机 | 指令**执行周期结束**后响应 | **总线周期(存取周期)结束**后即可让路 | | 响应速度 | 指令粒度(较慢) | 总线周期粒度(更快) | | 适用 | 低速设备(键盘、鼠标) | 高速块设备(磁盘、网卡、SSD) | | 硬件 | 接口 + 中断逻辑 | DMA 控制器(含地址/计数寄存器) | | 中断次数 | 每单位数据一次 | **整块传完一次**(后处理) | 💡 收伏笔:[[03-总线与接口|总线与接口]]说的"IRQ/DMA 通道"就是本篇的机制实体——每个设备申请一条 IRQ 线(中断源)或 DMA 通道。而"CPU 让出总线给 DMA"的本质是**总线仲裁**([[06-总线]]:DMA 控制器也是总线主设备,链式/独立请求里的一员)。 ## 五、通道与 IO 处理机(了解) - **通道**:能执行**通道程序**的专用处理器,进一步把"组块搬运的调度逻辑"也从 CPU 挪走——CPU 只发一条"启动通道"指令 - 层级:程序查询 < 中断 < DMA < 通道,**CPU 介入程度逐级下降** - 大型机(IBM z 系列)用通道;个人电脑用 DMA + 多核中断分发就够了 ## 六、盲点自测 1. MMIO 和独立编址的本质区别?GPU 显存属于哪种?(是否占用主存地址空间;MMIO) 2. 中断隐指令包含哪三件事?(关中断、保存断点、引出中断服务程序——硬件自动做) 3. 缺页是中断还是异常?(异常/内中断,同步于指令) 4. 响应优先级和处理优先级各由谁决定?(硬件排队器固定 / 屏蔽字软件设) 5. DMA 三种方式里最常用的是?(周期挪用/窃取) 6. DMA 结束后 CPU 为什么还要被打断一次?(后处理:校验、收尾) 7. 为什么磁盘用 DMA、键盘用中断?(数据粒度:块设备整块搬,字符设备一字节一事件) ## 七、动手玩 ```bash # 看你机器的中断分配(macOS 用 dmesg 不直观,Linux 更清晰) cat /proc/interrupts # Linux:每个 IRQ 号挂在哪个 CPU、是什么设备 # 注意观察:中断被"摊"到多个核上——多核中断分发的现实版 ``` ## 参考资料 - 王道《计算机组成原理考研复习指导》第 7 章 - CSAPP 第 8 章《异常控制流》——异常/中断/信号/进程上下文切换的统一视角 - [[08-IO管理]]——OS 怎么在硬件之上组织 I/O(缓冲、驱动、假脱机) ⬅️ [[06-总线|总线]] 🏠 [[00-基础与理论|00-基础与理论]] ➡️ [[00-数据结构总览|数据结构总览]]