1. 进程上下文的总体分类

一个进程的上下文主要分为三类:

  1. 用户级上下文(User-level Context)
  2. 内核级上下文(Kernel-level Context)

2. 各部分的内容

(1)用户级上下文

这是进程在用户态执行时的信息,主要包括:

进程虚拟地址空间

  • 用户虚拟地址空间(进程可访问的内存布局):
    • 代码段(Text Segment) → 存放程序的机器指令(只读)
    • 数据段(Data Segment) → 存放全局变量、静态变量
    • BSS段(BSS Segment) → 存放未初始化的全局变量和静态变量
    • 堆(Heap) → 动态分配(malloc/new)
    • 共享库映射区 → 动态库、mmap
    • 栈(Stack) → 函数调用、局部变量
  • 用户栈内容(函数调用参数、返回地址、局部变量)。
  • 用户态寄存器值(如 EAXEBXEIPESP 等)。
    • 通用寄存器(AX、BX、CX、DX、RAX、RBX …)。
    • 程序计数器 PC / 指令指针 IP(表示下一条将要执行的指令地址)
    • 栈指针 SP(当前栈顶位置)
    • 标志寄存器 EFLAGS / RFLAGS(条件码、中断允许位等)。
    • 段寄存器(CS、DS、SS 等)。
    • 浮点寄存器 / SIMD 寄存器(FPU/MMX/SSE/AVX 等,现代 CPU 上必须保存)。

👉 这些保证了进程从用户角度看能“接着原来的地方继续运行”。

(2)内核级上下文

当进程进入内核态(系统调用、中断、异常)时,需要的额外上下文:

  • 内核栈(每个线程一个,存放系统调用栈帧、局部变量)。
  • 内核态寄存器现场(陷入内核时,CPU 会把部分寄存器压入内核栈)。
  • 页表基址寄存器 CR3(指向该进程的页表,用于虚拟内存映射)。
  • 进程控制块 PCB / task_struct(操作系统保存的进程元数据):
    • 进程 ID、父进程 ID
    • 进程状态(就绪、运行、阻塞…)
    • 打开的文件描述符表
    • 信号处理信息
    • 调度优先级、时间片信息
    • 内存管理信息(mm_struct,指向代码段、堆、栈等的描述符)
    • 线程信息(thread_struct,保存寄存器内容等)

👉 这些是 OS 在调度和管理进程时必须用到的。

3. 进程切换过程

1. 触发条件

进程切换通常由以下中断或事件触发:

  1. 时钟中断(Timer Interrupt) → 实现时间片轮转
  2. I/O 外中断完成 → 阻塞进程变就绪
  3. 内中断/异常 → 除零、非法指令、断点
  4. 系统调用 → 软件中断(INT 指令)主动进入内核

注意:中断处理程序总是在内核态执行。

2. CPU 响应中断(进入中断处理程序)

  1. CPU 保存用户态基本上下文
    • 自动将以下压入内核栈:
      • RIP(下一条指令地址)
      • CS(代码段寄存器)
      • RFLAGS(标志寄存器)
      • RSP(用户栈指针)
      • SS(用户栈段寄存器)
  2. 切换特权级
    • CPU 切换到内核态栈(每个进程独立内核栈)
    • 段寄存器更新为内核态段
  3. 跳转到中断描述符表(IDT)指定的中断处理程序入口

3. 中断处理程序(Interrupt Handler)执行

  1. 保存内核态寄存器
    • 保存通用寄存器 RAX-R15、RFLAGS、RIP、RSP 等到 内核栈或上下文结构
    • 如使用浮点/SIMD,也可能保存 XMM/YMM/ST 寄存器
  2. 识别中断来源
    • 硬件中断(外中断) → 查询中断号、设备
    • 软件中断(系统调用) → 获取系统调用号
  3. 执行中断处理逻辑
    • 时钟中断:
      • 更新系统时间
      • 调用调度器决定是否切换进程
    • I/O 中断:
      • 将等待该设备的进程置为就绪
    • 异常:
      • 处理异常或发送信号给用户进程

4. 调度程序(Scheduler)执行

  1. 保存当前进程上下文(如果需要切换进程)
    • 用户态寄存器、内核栈指针保存到 PCB
    • 页表基址 CR3(如果不同进程页表不同)
  2. 选择下一个进程
    • 调度策略(时间片轮转、优先级、多级反馈队列等)
    • 更新 current_process 指向新进程 PCB
  3. 加载新进程上下文
    • 恢复用户态寄存器 RAX-R15、RIP、RSP、RFLAGS
    • 恢复浮点/SIMD 寄存器(按需)
    • 加载页表基址 CR3
    • 设置内核栈指针(Kernel Stack Pointer)

5. 返回用户态

  1. 执行 IRET 或 SYSRET 指令
    • RIP、RSP、RFLAGS、CS、SS 全部恢复
    • CPU 切换回用户态特权级
  2. 新进程继续执行
    • 如果没有切换进程,则原进程继续执行被中断的指令
    • 如果切换了进程,则新进程从上次暂停的地方继续运行

6. 数据结构和寄存器关系

内容 存放位置 说明
用户态寄存器(RAX-R15、RIP、RSP、RFLAGS) 内核栈 / PCB 上下文 用于恢复用户态执行
内核栈寄存器 PCB 保存当前内核栈位置
FPU/SSE/AVX 寄存器 PCB(按需) 浮点或向量寄存器
页表基址 CR3 CPU / PCB 切换进程时需要切换页表
调度信息 PCB 优先级、状态等
IDT / 中断向量 系统全局 中断入口地址表

7. 总结流程图(文字版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
用户态进程执行


中断触发/系统调用


CPU 自动保存用户态 RIP, CS, RFLAGS, RSP, SS → 内核栈


切换到内核栈,进入中断处理程序


保存通用寄存器、浮点/SIMD寄存器(上下文)


执行中断逻辑(时钟/I/O/异常/系统调用)


调用调度器(Scheduler)


是否切换进程?
┌─────┴─────┐
│ │
否 是
│ │
恢复原进程寄存器 保存当前进程上下文到 PCB
│ │
执行 IRET 恢复新进程上下文
│ │
用户态继续执行 IRET 返回用户态

💡 核心理解

  1. 中断触发 → CPU 自动压栈 → 内核栈切换 → 中断处理程序
  2. 中断处理程序 → 保存寄存器 → 执行中断逻辑 → 调度器决定切换
  3. 切换进程 → 保存当前进程上下文 → 恢复新进程上下文
  4. IRET 返回用户态 → 新进程继续执行

每个寄存器的意义

好的,我们来完整、系统地列举用户态寄存器,以 x86-64(64 位 CPU)为例,因为这是现代 PC/服务器常用架构。用户态寄存器就是进程在用户态运行时可以访问和使用的 CPU 寄存器,用于存放函数调用信息、中间计算结果、程序计数、栈指针等。

1. 通用寄存器(General Purpose Registers)

x86-64 用户态可以访问的 16 个通用寄存器:

寄存器 说明
RAX 累加寄存器,函数返回值
RBX 基寄存器,通常保存被调用者保存的数据(callee-saved)
RCX 计数寄存器,循环计数 / 函数参数传递
RDX 数据寄存器,函数参数 / I/O 操作
RSI 源索引寄存器,函数参数传递 / 内存操作源地址
RDI 目的索引寄存器,函数参数传递 / 内存操作目标地址
RBP 基址指针寄存器,指向栈帧底部(callee-saved)
RSP 栈指针寄存器,指向当前栈顶
R8–R15 额外通用寄存器(部分被调用者保存或调用者保存)

x86-64 的函数调用约定(System V AMD64 ABI)规定:

  • RBP、RBX、R12–R15 由被调用函数保存(callee-saved)
  • RAX、RCX、RDX、RSI、RDI、R8–R11 由调用者保存(caller-saved)

2. 程序计数寄存器

寄存器 说明
RIP 指令指针 / 程序计数器,指向下一条要执行的指令

3. 标志寄存器

寄存器 说明
RFLAGS 包含条件码(ZF、CF、SF 等)、中断允许标志 IF、方向标志 DF 等

4. 段寄存器(用户态可访问)

寄存器 说明
CS 代码段选择子
DS 数据段选择子
ES 附加段
FS 用户自定义段(常用于线程局部存储 TLS)
GS 用户自定义段(TLS 或系统信息)
SS 栈段选择子

注意:用户态只能访问段寄存器的低特权部分(Selector),不能修改内核段表。

5. 浮点 / SIMD 寄存器(可选,但用户态可用)

  • x87 FPU 寄存器:ST0–ST7(浮点栈寄存器)
  • SSE 寄存器:XMM0–XMM15(128 位)
  • AVX 寄存器:YMM0–YMM15(256 位),AVX-512 扩展还包括 ZMM0–ZMM31(512 位)

这些寄存器通常在用户态执行浮点或向量运算时使用,也属于用户态寄存器,需要在上下文切换时保存。

参考资料

B 站:深入理解进程,如何进行上下文切换?计算机科学中最深刻和最成功的想法之一。