Skip to content

CPU运行模式(内核态与用户态)

2026 大纲 一(三)1 CPU 运行模式,补充说明点名两个术语:内核模式、用户模式。

OS 凭什么管得住那些不听话的程序

上一节说操作系统要站在硬件和程序之间替所有程序做主。可 OS 自己也不过是一段代码, 和用户程序一样由同一个 CPU 执行——凭什么用户程序就得听它的?

如果答案是"因为 OS 写得早、跑得早",那它一点用也没有:一个用户程序只要执行一条 "关中断",OS 就再也拿不回 CPU;执行一条 I/O 指令,就能绕过 OS 直接读别人的磁盘数据。 软件层面的约定挡不住这些,因为执行指令的是硬件,硬件不认识谁是 OS

所以答案只能在硬件里:CPU 自己带一个模式位,处在某种模式下时,有一批指令 它压根就不执行。OS 运行在那个能执行全部指令的模式里,用户程序运行在另一个模式里。 这一个比特,就是操作系统全部权威的物理来源。

这一节要把三件事说清:这批"只有 OS 能用"的指令是按什么标准圈出来的用户程序硬要执行会发生什么以及两种模式之间怎么来回切。 最后一件事尤其要留意,因为它是不对称的——而那处不对称就是隔离能成立的全部技术含量。

一、两种运行模式

模式由 PSW(程序状态字)里的处理器状态位标识。CPU 每执行一条指令前都会拿这一位 和指令的权限要求对照。

模式别名模式位可执行的指令
内核态(内核模式)核心态、管态、特权态0所有指令(含特权指令)
用户态(用户模式)目态1(或 3)只有非特权指令

这张表最容易被答反的是右下角那一格。内核态能执行的是"全部指令",不是"只有特权指令"—— 内核里绝大多数代码也是普通的加减跳转。"某某态只能执行某类指令"这种句式, 只有"用户态只能执行非特权指令"这一句是对的。

硬件其实提供 0~3 共 4 个特权级,但通用操作系统只用了 0 级与 3 级, 中间两级在实践中被跳过了——这也是大纲只点名内核模式与用户模式的现实依据。

相应地,系统中运行的程序分为系统程序应用程序:两者是控制与被控制的关系, 前者有权管理与分配资源,后者只能申请与使用系统资源。

二、特权指令是按什么标准圈出来的

判据只有一条:这条指令是否可能影响其他进程或整个系统。 凡是能让"检查机制本身失效"的操作,一律划入特权。

按这条判据往下推,特权指令集中在三处——改硬件状态、改保护规则、改控制流权限

指令 / 操作特权指令依据
启动 I/O(in / out / DMA 启动)直接操作硬件,可读写他人数据
修改 PSW(程序状态字)会改变 CPU 模式位——这条是隔离的命门
关中断 / 开中断(修改 IF)影响响应中断的能力,关中断即可独占 CPU
设置 / 修改页表基址寄存器(PTBR)改地址翻译规则,等于换一套内存视图
修改重定位 / 界地址寄存器改内存保护边界
装入定时器影响时钟中断频率,可让 OS 再也夺不回 CPU
停机指令 hlt一条指令停掉整机
中断返回指令(iret从内核态降到用户态,会写模式位
系统调用指令(int 0x80 / syscall,即陷入指令 / 访管指令不是(用户态可执行)执行后立刻由硬件带入内核态
算术 / 逻辑运算、压栈不是不影响其他进程
访存指令 / 跳转指令不是越界由 MMU 硬件当场检测
设置断点(如 int 3不是调试器在用户态插进去就行

表里有两行是反直觉的,值得单独讲。

陷入指令不是特权指令。 它必须能在用户态执行,否则用户程序永远发不出请求, 系统调用这条路就断了。它的安全性不靠"禁止执行",而靠"执行后落到哪里"—— 执行它会立刻由硬件把模式位置 0,而进入内核后从哪一段代码开始跑, 是由内核的系统调用表决定的,用户改不了。它给了你进门的权利,但门后走哪条路不归你定。

iret 反过来必须是特权指令。 它要把模式位从 0 写回 1。如果用户态能执行它, 用户程序就可以自己构造一个"模式位=0"的 PSW 然后加载它,隔离当场失效。

三、隔离的闭环:用户态执行特权指令会怎样

"特权指令只能在内核态执行"这句话本身不构成保护——它只是一条规定。 真正让隔离成立的,是"违规时会发生什么"。

图里三步各自都不能少。指令根本没被执行——不是"先执行再检查", 不存在"已经把 I/O 端口写坏了才报错"这种事,检查发生在译码阶段。 产生的是异常(内中断)而不是外中断——它由当前这条指令自身引发,与外部设备无关。 异常处理程序运行在内核态——违规者自己没有任何处置权。教材给出的处理原则是: 非法指令、用户态使用特权指令、地址越界、非法存取等指令异常一律终止进程

所以"用户态不能执行特权指令"这句话只说了一半,完整的说法是 "指令不被执行 + 产生非法指令异常 + 进程被终止",保护是靠最后这一步合上闭环的。

四、判断一个「程序」在哪态运行

上面三节问的都是"指令",真题还会换个问法:这个程序运行在哪一态。 判据要换一条:看它需要访问什么资源。只用得着用户态可访问的资源,就在用户态; 要读写内核数据结构或执行特权指令,才在内核态。

按这条判据过一遍常见的几个:

  • 缺页处理程序要查页表、改 PCB、发起磁盘 I/O ——内核态。
  • 进程调度程序要读写 PCB 和就绪队列 ——内核态。
  • 时钟中断处理程序要改内核时钟变量和 PCB 的时间字段 ——内核态。
  • 命令解释程序(shell)——用户态

最后这个最容易判错,因为开机就有它,看起来像 OS 的一部分。但 bash、zsh、cmd 都只是普通的用户进程,和 vim、git 没有区别,只是被设置成开机自动启动而已。 它的工作流程是「读输入 → 解析命令 → fork()exec()wait()」, 每一步都是用户态代码。中间那几个是系统调用,shell 通过它们陷入内核, 但发起调用的代码在用户态,被调用的服务才在内核态。 "它调用了系统调用"不等于"它运行在内核态",否则所有程序都在内核态了。

五、特权指令 vs 敏感指令

这一组概念是虚拟机那一篇的地基,分界在于看的是哪件事

概念定义判据
特权指令只能在内核态执行,用户态执行会触发异常执行时会不会因权限不足而陷入
敏感指令读或改机器的关键状态(模式位、中断开关、页表基址、机器配置),或其行为随当前模式不同而不同它碰不碰系统全局状态

特权一定敏感,敏感不一定特权。 麻烦出在"敏感但不特权"这一类: 它读或改了关键状态,但在用户态执行时并不报错,而是悄悄返回一个当前模式下的结果, 或者干脆什么也不做

举个例子:某条读取中断开关状态的指令,在用户态执行既不陷入也不报错,只返回一个无意义的值。 对普通应用无所谓,但对一个被降到用户态运行的 Guest OS 就是灾难——它会据此做出错误判断, 而 VMM 根本收不到任何通知(没有陷入就没有通知)。所以当且仅当所有敏感指令都是特权指令时, "陷入-模拟"这套虚拟化方案才自动成立

六、两个方向的态切换:一边是硬件,一边是软件

进内核只有一条路——中断。它有三类:

触发方式说明举例
外中断(异步中断事件)来自 CPU 外部,与当前指令无关时钟中断、I/O 完成中断
内中断(同步异常事件)指令执行过程中出现问题缺页异常、除零异常、用户态执行特权指令
自愿性中断(主动陷入)用户程序主动请求 OS 服务系统调用(执行陷入指令 / 访管指令)

这两个方向是不对称的,而这处不对称就是隔离的全部技术含量。

上行(用户态 → 内核态)由硬件完成:中断、异常、陷入指令都会让硬件自动置模式位并交换 PSW, 整个过程没有任何一条指令是用户程序写的,因而用户伪造不出来

下行(内核态 → 用户态)由软件完成:OS 主动执行 iret

为什么不能让程序自己改模式位?把链条写全就明白了:模式位在 PSW 里 ⇒ 改 PSW 是特权指令 ⇒ 用户态执行它会触发非法指令异常并被终止 ⇒ "自行升权"这条路在硬件层面就是死的。 用户能做的只有"请求"。

还有一处要分清:态切换不等于进程切换。系统调用返回后通常仍回到同一个进程, 只是模式位变了两次。反过来则成立——进程切换必然发生在内核态,因为它要读写 PCB。

七、内核的组成:为什么偏偏是这几样

内核成员是被一条判据筛出来的:这件事在用户态做得成吗。做不成的才进内核。

层次组件为什么它必须在内核态
与硬件紧密相关时钟管理要装入定时器、响应时钟中断,都是特权操作;且时钟中断是抢占式调度的物理基础,若能被用户态关掉,OS 就再也夺不回 CPU
中断处理中断向量表、断点与现场保存都在内核空间,用户态连读都读不到;且中断到来时硬件已把模式位置 0
原语(原子操作)原语要求执行期间不可被打断,实现手段是关中断,而开关中断是特权指令
内核功能进程管理要读写 PCB、修改就绪队列,都是内核数据结构
存储器管理要改页表基址寄存器、界地址寄存器,都是特权指令
设备管理要执行 I/O 指令、操作设备寄存器,都是特权指令
硬件那 4 个特权级各自是干什么的,以及原语的原子性为什么只能靠关中断(想按教材原文口径答"处理器状态有几种",或想把"原语必须在内核态"这条推导链走通时展开)

先说 4 个特权级。 大多数计算机系统的处理器状态有 4 种,支持 0~3 级共 4 个特权级别:

级别名目权限
0 级处理 I/O 与中断权限最高,即内核态
1 级系统调用级
2 级共享库级
3 级应用程序级权限最低,即用户态

几乎所有通用操作系统实现都只使用了 0 级与 3 级,即简单区分内核态与用户态, 中间两级在实践中被跳过了。

再说原语。

原语(primitive)是由若干条指令组成的、完成某个特定功能的一段程序, 其执行必须一气呵成——要么全做完,要么一条都不做。

为什么必须这样?以"把一个进程从阻塞队列摘下、挂到就绪队列"为例:这个动作要改好几个指针, 做到一半被打断,队列就处于自相矛盾的中间状态;此时若切换到另一个进程也去动这个队列, 数据结构就彻底坏了。

实现手段最直接的一种就是关中断:

关中断执行原语全部指令开中断

关中断期间 CPU 不响应任何可屏蔽中断,没有中断就不会发生进程切换, 这段代码自然不可能被打断。而开关中断是特权指令——用户态程序连"关中断"这个动作都做不出来, 也就无法保证任何原子性。

推导链完整写出来是:原语要求执行期间不被打断 ⇒ 打断只可能来自中断(及由中断引发的进程切换) ⇒ 屏蔽办法是关中断 ⇒ 关中断是特权指令 ⇒ 用户态做不到 ⇒ 原语只能在内核态

这也解释了为什么原语必须:关中断期间时钟中断也被挡在门外, 原语越长,整个系统对外部事件的响应就越迟钝。

考点速记

  1. 模式由 PSW 中的处理器状态位标识。特权指令的判据只有一条——是否可能影响其他进程或整个系统——因而集中在改硬件状态、改保护规则、改控制流权限三处。
  2. 陷入指令不是特权指令(否则用户发不出请求),iret(否则用户能自行升权)。
  3. 隔离的闭环靠"违规会怎样"合上:指令不被执行 → 硬件产生非法指令异常 → 陷入内核 → OS 终止该进程。只说"不能执行"是半句话。
  4. 指令看权限,问程序看它要访问什么资源。shell 是用户程序——调用系统调用不等于运行在内核态。
  5. 两个方向不对称:上行由硬件完成(用户伪造不出),下行由软件完成(且 iret 是特权指令)。进内核只有中断一条路,含外中断、内中断、自愿性中断三类。
  6. 特权一定敏感,敏感不一定特权;虚拟化的"陷入-模拟"方案要求两者重合。

这一节在真题里被考过的形式

考法高度集中,只有两种问法,而且四道题里三道都在同一个模子里。

  • 给四条指令,问哪条不能在用户态执行 / 只能在内核态执行(2014-25、2021-23)。这是最标准的问法,直接套"会不会影响其他进程或整机"。2014-25 答关中断:用户态若能关中断,恶意程序关掉再死循环,时钟中断进不来、调度器叫不醒它,整机就被锁死。2021-23 答 I/O 指令:放给用户态,任何程序都能直接操作磁盘网卡,设备保护全废。⚠️ 这两道题的干扰项都放了 trap 指令,而它恰恰不是特权指令——这是本节被反复利用的唯一一个反直觉点。
  • 判断"某态只能执行某类指令"的四种组合(2022-27)。答用户态只能执行非特权指令。四个选项把"只能 + 特权/非特权"和"用户态/内核态"两两配齐,只有这一种成立。⚠️ 最有迷惑力的是"内核态只能执行特权指令"——内核里大量代码也是普通指令,"只能"这个词就把它判死了。
  • 给四个程序,问哪个在用户态执行(2011-24)。答命令解释程序(shell)。另三个(缺页处理、进程调度、时钟中断处理)都要动内核数据结构。⚠️ 这道题换了问法,判据从"指令权限"变成"要访问什么资源",按前一条判据是答不出来的。

复习优先级必须拿满。这一节考点窄、判据单一,把特权指令那张表的三处归类 (改硬件状态 / 改保护规则 / 改控制流权限)记住,加上 trapiret 这一对反例, 选择题就没有失分空间。第四节那条"看程序访问什么资源"的判据要单独记, 它和前面几节用的不是一套。

易错:把陷入指令(trap / 访管指令)当成特权指令。它必须能在用户态执行,安全性靠"执行后由硬件带入内核、入口由内核决定"来保证。

易错:说"内核态只能执行特权指令"。内核态能执行全部指令;只有"用户态只能执行非特权指令"这一句是对的。

易错:把"用户态不能执行特权指令"当成完整答案。完整的是"指令不被执行 + 产生非法指令异常 + 进程被终止"。

易错:认为 shell 是 OS 的一部分、运行在内核态。它是普通用户进程;调用系统调用的代码仍在用户态。

易错:把用户态执行特权指令产生的当成外中断。它由当前指令自身引发,是内中断(异常)

易错:把态切换当成进程切换。系统调用返回后通常仍是同一进程;反过来"进程切换必然在内核态"才成立。

教材出处
  • 孙钟秀、费翔林《操作系统教程》(第 6 版)2.1 处理器(p43):处理器状态位是"程序状态字中的比特位";"大多数计算机系统的处理器状态有 4 种,分别支持 0~3 级共 4 个特权级别",而"几乎所有通用操作系统实现都只使用了 0 级与 3 级";处理器状态转换一节给出"只有中断才会使处理器从用户态向内核态转换"及其三类情况,并指出"计算机系统通常会提供一条称作加载程序状态字的特权指令(如 iret 指令),用于实现从内核态返回用户态"。
  • 同书 2.2.2 中断源·程序性中断事件(p46):处理原则中明确"非法指令、用户态使用特权指令、地址越界、非法存取等指令异常:终止进程"。
  • 同书 1.3.5 系统调用(p25):"由于系统调用而引起处理器中断的机器指令称为陷入指令(trap),它是非特权指令,在用户态下执行时会产生 CPU 模式切换。"

相关知识

操作系统基本概念与发展历程中断和异常的处理系统调用虚拟机

真题练习