Appearance
一次调用发生了什么:把动作展开,逐点问「这一步归谁管」(专题总纲)
Intro
这一类题的题面看起来毫不相干:一道给硬盘的引导记录,一道给六个打乱编号的操作,一道给一段十行的 C 程序和一张内存布局图。没有公式可套,也没有数要算。
但它们给的东西是同一样:一次具体的动作——
- 2021-46:开机。从按下电源到操作系统跑起来。
- 2023-46:按一次键。进程 P 调
read()要一个字符,直到它拿到。 - 2025-46:跑一遍
main()。一个 C 程序从头执行到free()。
然后沿着这个动作,一个点一个点地问同一件事:
这一步(这个东西)归谁管。
归硬件和 ROM 固件,归内核,归驱动,还是归用户程序自己。这一问三道题全都有:
| 题面在哪里问了「归谁管」 | |
|---|---|
| 2021-46 | 第 (3) 问「扇区划分」「根目录建立」分别归第 (2) 问的哪一步(第 (1)(2) 两问问的是执行顺序,不是归属) |
| 2023-46 | 第 (3) 问「完成上述哪个操作的代码属于键盘驱动程序」 |
| 2025-46 | 第 (2) 问「其直接调用的哪些函数的功能需要通过执行驱动程序实现」 |
答对归属,剩下的顺序、进程状态、CPU 模式,几乎都是跟着掉下来的。
五个「谁」
运行时的一次动作从头到尾,只在这五层之间传手(2021 那道的制盘链是离线操作,不走这五层)。下笔前先在草稿纸上把这五行写出来,再往里填:
| 层 | 谁在跑 | 三道真题里的实例 |
|---|---|---|
| 硬件与固件 | CPU 复位逻辑、ROM 里的引导程序、设备控制器 | ROM 中的引导程序(2021);键盘控制器收到字符发出中断(2023) |
| 内核·中断管理 | 中断响应与中断处理程序的启动 | ④ 启动键盘中断处理程序(2023) |
| 内核·设备驱动 | 和某一类设备控制器打交道,读写它的寄存器 | ③ 把字符从键盘控制器读入系统缓冲区(2023);scanf / printf 背后的键盘、显示器驱动(2025) |
| 内核·进程管理与调度 | 建 PCB、插队列、选下一个进程 | ② 插阻塞队列、① 插就绪队列(2023);PCB 所在的内核区(2025) |
| 用户程序自己 | 用户态的指令与它自己的数据 | main() 的代码、length、ptr、malloc 出来的那 100 字节(2025) |
而每一点上要问的,一共只有五件事。哪几件被问到,逐题不同:
| 要问的 | 2021-46 | 2023-46 | 2025-46 |
|---|---|---|---|
| ① 这一步(这个东西)归谁管 | ✅ | ✅ | ✅ |
| ② 这些步骤的先后顺序 | ✅ 两条链 | ✅ 一条链 | — |
| ③ 进程此刻处于什么状态 | — | ✅ | ✅ |
| ④ CPU 此刻是内核态还是用户态 | — | ✅ | — |
| ⑤ 这段代码 / 这个变量落在哪个区 | — | — | ✅ |
三道题共有的只有第 ① 件。 第 ② 件出现在 2021 和 2023 那两道上(2025 那道从头到尾没让排过序);第 ④ 件只有 2023 那道问过一次。所以下笔时先答归属,别一上来就画状态转换图。
顺序怎么排:看后一棒要用到前一棒的什么产物
排序这一问不用背。只要看一条:这一步开工的前提条件,是由哪一步生产出来的。
2021 年那道的启动链。 题面写明「硬盘第一个扇区存放主引导记录,其中包含磁盘引导程序和分区表」「每个分区的第一个扇区存放分区引导程序」——顺序就藏在这两句里:
ROM 中的引导程序 ← 加电时只有它可以直接执行,磁盘还没人去读
磁盘引导程序 ← 它要先被 ROM 读进内存;它读分区表,选出要启动哪个分区
分区引导程序 ← 它在某个分区的第一个扇区里,得先选出分区才知道去读谁
操作系统的初始化程序 ← 它在分区里的 OS 镜像中,得先由分区引导程序装进来2021 年那道的制盘链同理,前一步的产物是后一步的操作对象:
物理格式化 → 产物:磁道上的扇区 (没有扇区就无处存数据)
磁盘分区 → 产物:若干个分区 + 分区表 (逻辑格式化是针对单个分区做的)
逻辑格式化 → 产物:文件系统结构(引导记录、FAT / inode 表、根目录、数据区)
操作系统安装 → 往已经建好的文件系统里写文件2023 年那道的输入链换成了「前提条件」:字符没进缓冲区就没法唤醒 P,中断处理程序没启动就轮不到驱动去读控制器。
边界必错点
⑥ 和 ③ 之间隔着一个 ④。(2023 年那道第 (1) 问)用户按下键、字符已经躺在键盘控制器里了,但要先由 ④ 启动键盘中断处理程序,③ 才有机会把它读进系统缓冲区。题面把 ④ 和 ③ 拆成两个独立编号,拆点就在这里——这条边一错,(1) 问三个空里的一个就没了。
「CPU 一定切走」这件事挂在 ② 上。(2023 年那道第 (2) 问)题干原话是「在上述哪个操作之后 CPU 一定从进程 P 切换到其他进程」。P 被插进阻塞队列(②)那一刻就不再可运行,CPU 必须去跑别人。⑥ 用户按键是很久以后的事,那时 CPU 早在跑别的进程了。这一问问的是「从哪一步之后开始成立」,找的是最早的那个点。
进程状态和 CPU 模式要分开各给一个值。(2023 年那道第 (4) 问)题干把它写成两句:「进程 P 处于什么状态?CPU 处于内核态还是用户态?」P 在阻塞队列里躺着(① 还没执行到),CPU 正在跑中断处理这段内核代码——这两个描述的是两码事,一个说 P 自己在不在跑,一个说 CPU 上当前那段代码权限多高。答成「P 处于内核态阻塞」会丢掉一半分。
指针自己在哪、它指向的东西在哪,是两个位置。(2025 年那道第 (3) 问)题干先问「变量 ptr 被分配在哪个区域」,再问「ptr 指向的字符串位于哪个区域」。就看声明写在 main 里面还是外面:char *ptr; 写在 main 外面,是全局变量,落在读 / 写数据段;int length; 写在 main 里面,是局部变量;题面专门加了一句「若变量 length 没有被分配在寄存器中」,排除掉寄存器这一种可能之后才落在用户栈——这句假设不是废话,它正是这一空要单独问的原因;而 malloc(100) 要来的那 100 字节在堆区。
碰外设的才走驱动。(2025 年那道第 (2) 问)题干问「其直接调用的哪些函数的功能需要通过执行驱动程序实现」。main 里一共直接调了五个:malloc、scanf、strlen、printf、free。逐个过一遍标准「它最终要不要去动一个外部设备」:scanf 动键盘、printf 动显示器,这两个走驱动;malloc / free 走 brk、mmap 这类系统调用,动的是内存;strlen 是纯计算,连内核都不进。进内核和走驱动是两道不同的门槛。
扇区和根目录建在不同的步骤里。(2021 年那道第 (3) 问)扇区是磁盘硬件上的东西,在物理格式化那一步划出来;根目录是文件系统里的东西,和 FAT / inode 表一起在逻辑格式化那一步建。判断标准仍是归属:这个东西属于硬件层还是文件系统层。
一道题的答卷长什么样
以 2023 年那道为例。这一类题的卷面很短,但推链的草稿必须先在旁边打出来——链一旦排错,(1)(2)(4) 三问会连着错。
草稿:把这次 read() 从头到尾摊平,一行一步
P 执行 read() 系统调用 → 进内核 → 发现键盘缓冲区里还没有字符
② 将进程 P 插入阻塞队列 ← P 让出 CPU,调度程序去选别的进程
⋯⋯ 时间流逝,CPU 在跑别的进程 ⋯⋯
⑥ 用户在键盘上输入字符 ← 键盘控制器收到字符,向 CPU 发出中断
④ 启动键盘中断处理程序 ← CPU 进内核态,保护现场
③ 将字符从键盘控制器读入系统缓冲区 ← 这一步是键盘驱动干的活
① 将进程 P 插入就绪队列 ← 到这一步 P 才对调度程序可见
⋯⋯ 等到调度程序选中 P ⋯⋯
⑤ 进程 P 从系统调用返回 ← 拿到字符,回到用户态卷面
(1) 完整顺序:② → ⑥ → ④ → ③ → ① → ⑤
① 的前一个操作 = ③ ① 的后一个操作 = ⑤ ⑥ 的后一个操作 = ④
(2) ② 之后,CPU 一定从进程 P 切换到其他进程
① 之后,CPU 调度程序才能选择进程 P 执行
(3) ③(将字符从键盘控制器读入系统缓冲区)的代码属于键盘驱动程序
(4) 进程 P:阻塞状态
CPU:内核态答案的重点只有那几个编号和那两个词——写再多解释也不会多给分,所以卷面按上面那样直接给答案就够,草稿留在旁边给自己核对用。(408 官方不公布小问级细则,本站按同一标准拟了一份用于对照,专题页上每道题下面那条分值条就是它。)
⚠️ (1) 问只要三个邻位,题干没让写完整顺序。但完整顺序要在草稿上排出来——三个邻位是从这条链上读出来的,跳过排链直接猜邻位,⑥ 后面那一格最容易填成 ③。
第二组的卷面:一问一行,别写解释
2025 年那道 9 分,三小问各 3 分,每一空只要一个名词,写解释不额外加分。
(1) PCB 在哪个区域 → 操作系统内核区
scanf 等键盘输入时进程 → 阻塞态
(2) main() 的代码在哪 → 只读代码段(.text)
哪些函数要走驱动 → scanf()(键盘驱动)、printf()(显示器/终端驱动)
(3) ptr 在哪 → 读/写数据段(它是全局变量)
length 在哪 → 用户栈
ptr 指向的字符串在哪 → 堆区(malloc 分配的)⚠️ 第 (3) 问的 length 有个前提不能漏:题面写的是「若变量 length 没有被分配在寄存器中」。 局部变量本来有寄存器和栈两种去处,是这句假设把寄存器排除掉之后才唯一。 答题时把这个前提抄一句,比直接写「用户栈」稳。
另外注意 ptr 和 ptr 指向的字符串是两个东西:指针变量本身按它的声明位置归区, 它指向的那块内存按分配方式归区。这两空答成同一个区,是这一问最常见的丢分。
真题的两种形态
第一组 · 把打乱的步骤排成链(2021-46、2023-46)——题面把一个动作的若干步骤打乱、编上号,先排出正确顺序,再在链上定位某件事发生在哪一步、哪一步之后。2021 那道要排两条链(启动的 4 个程序、制盘的 4 个操作),2023 那道排一条链(6 个操作)。做法是上面那条规则:后一棒要用到前一棒的什么产物 / 什么前提条件。
第二组 · 沿一次运行逐点问归属(2025-46)——不排序,给一段 C 程序和一张地址空间布局图,逐个对象问它落在哪个区、归谁管,外加一问进程此刻的状态。做法是先给每个对象定性:全局的还是局部的、编译期就有的还是运行期申请的、OS 私有的还是用户程序自己的,定性完位置就唯一了。
交卷前扫一眼
先在草稿上把链摊平 · 每一点先问「归谁管」· 排序看的是后一棒要用前一棒的什么 · 进程状态与 CPU 模式分开各答一个 · 指针自己的位置与它指向的位置分开答 · 碰外设的才走驱动
配套内容
- 操作系统的引导|内核态与用户态|中断与异常|系统调用
- 操作系统的体系结构|进程的内存映像|链接与装入
- 进程的状态与转换|进程控制|上下文切换|线程
- I/O 软件层次结构|设备驱动程序接口|I/O 控制方式
- 想动手看一遍:上下文切换模拟器
考纲要求、但这 3 道真题没有正面考过的(专题的巩固栏里配了题):
- 用户态 → 内核态一共有哪几条路——系统调用陷入、外部中断、内中断异常这三条,2023 年那道只问了中断处理时 CPU 在哪个态,没往回问「是从哪条路进去的」;另外两道连模式都没问。三道题干里「异常」两个字一次都没出现
- 哪些指令是特权指令、用户态执行了会发生什么——三道真题从头到尾没出现过「特权指令」这个词。它是「CPU 为什么要分两态」的另一半:一态问的是当前跑的是谁,另一态问的是当前这条指令准不准跑
- 挂起态与七状态模型——2023 和 2025 那两道都问到了阻塞态,但都是内存里的阻塞。进程被整个换出到外存之后是什么状态、换出的阻塞进程等到事件之后又变成什么,三道题里「挂起」「换出」「对换」一个字都没有
- 一次「运行 → 阻塞」切换到底要保存哪些东西——2025 年那道只问了 PCB 位于哪个区域,没问 PCB 里装着什么;2023 年那道说了 ② 之后「CPU 一定从进程 P 切换到其他进程」,也没往下问这次切换搬走了什么、哪些由硬件自动压栈、哪些由内核代码写进控制块
- 进程之间切换与同一进程内线程之间切换差在哪——三道真题里「线程」两个字一次都没出现,地址空间与页表要不要跟着换这件事自然也没被问过
- 同一次调用在宏内核与微内核下差几次态切换——三道题都默认了宏内核(所有服务都在内核里),OS 结构本身没被问过。换成微内核,同一次「读文件」的调用链会长出好几段 IPC,态切换次数跟着变
- MBR 里面装着什么——2021 年那道的题面给了「主引导记录,其中包含磁盘引导程序和分区表」,但只让排顺序,没问过 MBR 占几个扇区、分区表能放下几个表项、由此主分区最多几个
逐题精讲(建设中)——真题作答与 AI 判分入口见站内大题专题。