一、TSS 的核心作用

TSS(Task State Segment,任务状态段)是 x86 架构中用于任务切换和特权级切换的关键数据结构,主要功能包括:

  1. 保存任务状态: 存储任务的寄存器状态(如通用寄存器、段寄存器、EFLAGS、EIP 等),用于上下文切换。
  2. 管理特权级堆栈: 为每个特权级(Ring 0~3)提供独立的内核栈指针(SS 和 ESP),确保特权级切换时能正确加载栈。
  3. 处理中断/异常: 在发生中断或异常时,CPU 自动从 TSS 中加载目标特权级的栈指针,确保内核态代码有安全可用的栈空间。

二、TSS 与栈指针的关联

TSS 与栈指针的关系体现在特权级切换时的自动栈管理。具体机制如下:

1. TSS 中存储的栈指针字段

在 TSS 结构中,以下字段定义了不同特权级的栈指针:

  • SS0、ESP0:Ring 0(内核态)的栈段选择符和栈顶指针。
  • SS1、ESP1:Ring 1 的栈指针(通常不使用)。
  • SS2、ESP2:Ring 2 的栈指针(通常不使用)。
2. 特权级切换时的自动加载

当 CPU 从低特权级(如用户态,Ring 3)切换到高特权级(如内核态,Ring 0)时:

  1. 触发条件: 通过中断、异常或系统调用(如 int 0x80)触发特权级切换。
  2. 加载内核栈指针: CPU 自动从 TSS 的SS0 和 ESP0字段中加载 Ring 0 的栈段选择符和栈顶指针,切换到内核栈。
  3. 保存用户态上下文: 原用户态的寄存器状态(SS、ESP、EFLAGS、CS、EIP 等)被压入新加载的内核栈中。
3. 示例:系统调用流程
// 用户态触发系统调用(如int 0x80)
asm("int $0x80");
 
// CPU自动执行以下操作:
// 1. 从TSS的SS0和ESP0加载内核栈指针。
// 2. 将用户态的SS、ESP、EFLAGS、CS、EIP压入内核栈。
// 3. 跳转到内核的中断处理函数(如system_call)。
4. 操作系统对 TSS 的初始化

操作系统需为每个任务(或 CPU 核心)初始化 TSS,确保其包含正确的内核栈信息:

; 示例:设置TSS的Ring 0栈指针(SS0=0x10,ESP0=0x8000)
mov eax, tss_entry
mov [eax + 4], 0x10     ; SS0
mov [eax + 8], 0x8000   ; ESP0

三、为什么需要 TSS 管理栈指针?

  1. 特权级隔离: 用户态(Ring 3)代码无法直接访问内核栈,必须通过 TSS 提供的安全指针切换。
  2. 防止栈溢出攻击: 独立的内核栈与用户栈物理隔离,避免用户程序破坏内核栈数据。
  3. 自动化的上下文保存: CPU 利用 TSS 中的栈指针自动保存用户态上下文,无需软件手动管理栈切换。