
段寄存器Segment Registers。在历史上它们是实现内存分段机制的核心但在现代64位操作系统长模式下它们的作用已经发生了根本性变化更多是作为“遗产”和“模式标记”存在。简单来说CS、SS、DS、ES是CPU内部用于访问内存的“基地址指针”但它们指向的不是内存地址而是内存段描述符表GDT/LDT中的一个索引该索引指向一个描述符其中定义了段的基地址、长度、访问权限和类型。各段寄存器的作用段寄存器全称主要用途现代长模式下的角色CSCode Segment代码段指向当前正在执行的代码段包含RIP指令指针。必须且L164位模式、DPL3用户态或0内核态其基址通常视为0。SSStack Segment栈段指向当前栈段与RSP栈指针配合使用。在64位模式下基址固定为0但仍用于特权级检查如iret判断是否切换栈。DSData Segment数据段指向默认的数据段用于大部分数据访问。基址固定为0在64位模式下大多数情况下被忽略仅用于少数特殊指令如mov到段寄存器。ESExtra Segment附加段用于字符串操作指令如movs、cmps的附加数据段。基址固定为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表中的索引。TI0 表示GDT1 表示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位基址可任意指定最大4GBCS/SS/DS/ES基址强制为0大小由段限制Limit定义CS/SS/DS/ES大小视为全64位地址空间FS/GS可自定义基址FS和GS基址可由MSR独立设置IA32_FS_BASE/IA32_GS_BASE权限检查通过段描述符中的DPL和选择子中的RPL共同决定仍通过CS.DPL和RPL进行特权级检查如iret使用场景几乎所有内存访问都通过段寄存器除CS/SS用于权限控制外DS/ES几乎被忽略FS/GS用于特殊用途TLS、CPU数据Linux内核中swapgs的妙用在x86_64上FS和GS是少数仍被广泛使用的段寄存器。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必须存在L1表示64位模式SS仅在iret等特权级切换时使用基址固定为0用于判断是否需要栈切换DS / ES基本弃用基址固定为0仅少数指令如movs会使用但通常不设置FS线程局部存储TLS用户态指向TEB通过wrfsbase切换GS内核CPU数据结构如per_cpu通过swapgs在用户态/内核态间切换