Appearance
题目
下列操作中,在内核模式执行的是( )。
错因
A
把"编译"误当成"系统功能",以为编译器要直接操作底层资源所以应在内核态。其实编译程序(如 gcc)只是普通的用户态应用:它读源代码、写目标文件,全程通过普通的文件 I/O 系统调用完成,本身不需要任何特权指令。它"看上去重要"不等于"运行在内核态"。
B
混淆了"链接程序(linker,如 ld)"与"装入时的地址重定位"。链接的工作是把多个目标文件合并、解析符号、确定逻辑地址,完全在用户态完成;它输出的是可执行文件,并不直接把程序送进内存。把"链接"和"装入"当成同一阶段的人,会误以为链接也得动内存管理而归到内核态。
D
把"命令解释程序"(shell,如 bash、cmd)当作 OS 的核心组件而归到内核。但 shell 只是一个普通进程,它通过 fork/exec 调用内核去启动其他程序,自身解析命令行字符串、维护历史记录等动作都在用户态完成。Linux 上 bash 跑在用户空间就是最直接的反例。
总解析
判定原则:一个程序是不是在内核态运行,看它是否必须使用特权指令——访问硬件、修改页表、分配物理内存、屏蔽中断等动作只能在内核态做;纯粹的数据加工(读/写文件、字符串处理、算术运算)通过系统调用走一遭就够了,本体仍在用户态。
逐项分析:
| 选项 | 程序 | 主要工作 | 需要特权指令吗 | 归属 |
|---|---|---|---|---|
| A | 编译程序 | 词法/语法分析、生成目标代码 | 否(只是文件读写) | 用户态 |
| B | 链接程序 | 合并目标文件、解析符号、重定位 | 否(只是文件读写) | 用户态 |
| C | 装入程序 | 为新进程分配物理内存、建立页表、把代码段/数据段映射进虚地址空间、初始化 PCB | 是(修改页表、分配物理页框) | 内核态 |
| D | 命令解释程序 | 解析命令、调用 fork/exec 启动子进程 | 否(自己只是个普通进程) | 用户态 |
A、B、D 三者都是"用户态应用程序",它们如果需要内核服务(比如读文件、创建进程),就发起系统调用进内核走一趟,回来仍在用户态。只有装入程序因为要直接操作页表、分配物理内存、设置进程上下文,本质上是 OS 内核的一部分,必须在内核态执行。
最终答案是 C。
编者注(解题技巧):判定"是否在内核态"只看一句话——这个程序要不要直接动页表/物理内存/特权指令。要动 → 内核态;只读写文件就能完事 → 用户态。"听起来重要"或"和 OS 相关"都不算证据。