Intel Segment Registers
2026/8/4 15:13:43 网站建设 项目流程

段寄存器(Segment Registers)。在历史上,它们是实现内存分段机制的核心,但在现代64位操作系统(长模式)下,它们的作用已经发生了根本性变化,更多是作为“遗产”和“模式标记”存在。

简单来说,CSSSDSES是CPU内部用于访问内存的“基地址指针”,但它们指向的不是内存地址,而是内存段描述符表(GDT/LDT)中的一个索引,该索引指向一个描述符,其中定义了段的基地址、长度、访问权限和类型。


各段寄存器的作用

段寄存器全称主要用途现代长模式下的角色
CSCode Segment(代码段)指向当前正在执行的代码段,包含RIP(指令指针)。必须,且L=1(64位模式)、DPL=3(用户态)或0(内核态),其基址通常视为0。
SSStack Segment(栈段)指向当前栈段,与RSP(栈指针)配合使用。在64位模式下,基址固定为0,但仍用于特权级检查(如iret判断是否切换栈)。
DSData Segment(数据段)指向默认的数据段,用于大部分数据访问。基址固定为0,在64位模式下,大多数情况下被忽略,仅用于少数特殊指令(如mov到段寄存器)。
ESExtra Segment(附加段)用于字符串操作指令(如movscmps)的附加数据段。基址固定为0,仅用于少数特定指令(如rep movs的扩展)。
FS/GS附加数据段(用户态/内核态)用于线程局部存储(TLS)、CPU核心数据结构等。可自定义基址(通过IA32_FS_BASE/IA32_GS_BASEMSR),是64位系统中唯一仍广泛使用的段寄存器。
FS/GS(用户态)线程本地存储(TLS)每个线程有其自己的FS基址,指向TEB(线程环境块)等。通过wrfsbase等指令切换,或通过swapgs在内核态/用户态间切换。

段选择子(Segment Selector)的结构

段寄存器中存储的是一个16位的段选择子,它不是一个直接地址,而是GDT(全局描述符表)或LDT(局部描述符表)中的一个偏移量。

+----------------+----------------+----------+ | Index (13位) | TI (1位) | RPL (2位)| +----------------+----------------+----------+
  • Index:在GDT/LDT表中的索引。

  • TI:0 表示GDT,1 表示LDT。

  • RPL:请求的特权级(0~3),用于权限检查。


段描述符(Segment Descriptor)的结构

段选择子指向的段描述符,才是真正定义段属性的地方。它包含了段的基地址、大小、类型和权限。

+------------------+------------------+------------------+------------------+ | Base (31:24) | Flags (G|D/B|L|AVL) | Limit (19:16) | Access Rights | +------------------+------------------+------------------+------------------+ | Base (23:16) | Base (15:0) | Limit (15:0) | +------------------+------------------+------------------+
  • Base:段的线性地址基址(在长模式下,通常为0)。

  • Limit:段的大小(在长模式下,通常忽略)。

  • Access Rights:段类型(代码/数据)、可读/可写、特权级(DPL)等。


64位长模式下的段寄存器

IA-32e长模式(即x86_64)下,段寄存器的行为与保护模式有显著不同:

特性保护模式(32位)长模式(64位)
基址可任意指定(最大4GB)CS/SS/DS/ES基址强制为0
大小由段限制(Limit)定义CS/SS/DS/ES大小视为全64位地址空间
FS/GS可自定义基址FSGS基址可由MSR独立设置(IA32_FS_BASE/IA32_GS_BASE
权限检查通过段描述符中的DPL和选择子中的RPL共同决定仍通过CS.DPLRPL进行特权级检查(如iret
使用场景几乎所有内存访问都通过段寄存器CS/SS用于权限控制外,DS/ES几乎被忽略,FS/GS用于特殊用途(TLS、CPU数据)

Linux内核中swapgs的妙用

在x86_64上,FSGS是少数仍被广泛使用的段寄存器。Linux内核通过IA32_GS_BASEMSR(在entry_64.S中由swapgs指令切换)来实现内核态与用户态之间的高效切换。

; 进入内核时 swapgs ; 将用户态GS基址存入 MSR,加载内核态GS基址 mov rax, [gs:0x10] ; 访问当前CPU的per_cpu数据结构 ; 返回用户态时 swapgs ; 恢复用户态GS基址 iretq

总结

寄存器现代64位下的用途备注
CS标记当前特权级(内核/用户),基址固定为0必须存在,L=1表示64位模式
SS仅在iret等特权级切换时使用,基址固定为0用于判断是否需要栈切换
DS / ES基本弃用,基址固定为0仅少数指令(如movs)会使用,但通常不设置
FS线程局部存储(TLS)用户态指向TEB,通过wrfsbase切换
GS内核CPU数据结构(如per_cpu通过swapgs在用户态/内核态间切换

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询