Intel 64/x86_64/IA-32/x86处理器段寄存器 - 32位段寄存器/64位段寄存器

Segment Registers

本节主要讲述Intel处理器中的段寄存器,用于支持处理器的段式存储器管理机制。16位的8086/Intel286处理器有4个段寄存器CS/DS/SS/ES。32位的处理器运行在保护模式下时,除了先前的4个段寄存器,还引入了两个新的段寄存器FS/GS,这些寄存器都是16比特位宽。64位模式下的段寄存器有特殊性,后面有一节介绍。程序员

IA-32处理器中的段寄存器(CS/DS/ES/SS/FS/GS)用于保存16位宽的段选择符(segment selector)。要访问存储器中的特定段,对应的段选择符必需要加载到正确的段寄存器中。安全

当设计应用程序代码时,程序员一般使用汇编器的指示符和符号(directives and symbols)来建立段选择符。汇编器和其余的工具软件会根据这些指示符和符号生成真正的段选择符值。若是是设计系统程序代码,程序员则能够直接建立段选择符(之后有专题介绍)。数据结构

段寄存器如何被使用主要取决于操做系统/管理软件采用的存储器管理模型的类型。工具

当使用平坦(未分段的)存储器模型时,段寄存器加载的段选择符指向重叠的段,在线性地址空间中,每一个段的起始地址都是0(参看下图)。这些重叠的段构成了程序可见的线性地址空间。一般,会定义两个重叠的段:一个是代码段,另外一个是数据/栈段。CS寄存器指向代码段;其余的全部段寄存器指向数据/栈段。spa

 

当使用分段存储器模型时,每一个段寄存器一般会加载不一样的段选择符,这样段寄存器指向线性地址空间中不一样的段(参看下图)。任什么时候候,程序能够同时访问线性地址空间中最多6个段。若是要访问的段没有段寄存器指向,程序必须先将段对应的段选择符加载到某个段寄存器以后,才能够访问段中的数据。操作系统

每一个段寄存器都关联下列三种存储类型(即段类型)之一:代码段,数据段,栈段。例如,CS段寄存器包含代码段的段选择符,代码段保存正在执行的指令。处理器从代码段读取指令时,使用有CS寄存器中的段选择符与EIP寄存器联合构成的逻辑地址。EIP保存要执行的下一条指令在代码段中的偏移量。CS寄存器不能有应用程序显式地的加载。相反,能够经过某些指令或处理器内部操做隐式地加载。这些指令/内部操做,例如过程调用,中断处理,或者任务切换,用于改变程序的执行流,从而致使更新CS寄存器。设计

DS/ES/FS/GS这四个寄存器指向四个数据段。多个数据段的存在容许高效地且安全地访问不一样的数据结构类型。例如,能够建立以下的四个数据段:第一个数据段保存当前程序模块的数据结构,第二个数据段保存更高级别程序模块导出的数据,第三个数据段保存动态建立的数据结构,最后一个数据段保存另外一个程序共享出来的数据。要想访问更多的数据段,应用程序必须按需将数据段对应的段选择符加载到DS/ES/FS/GS寄存器中的其中一个当中。blog

SS寄存器包含栈段的段选择符,这里栈段用于存储程序/任务/当前正在执行的处理器程序的栈帧。全部的栈操做都使用SS栈段寄存器来定位栈段。与CS代码段寄存器不一样,SS寄存器能够显式地加载,这样就容许应用程序创建多个栈段,并在这些段间切换。it

Segment Registers in 64-Bit Mode

在64位模式下:处理器把CS/DS/ES/SS的段基都看成0,忽略与之关联的段描述符中的段基地址。这样就为代码/数据/栈建立了平坦的地址空间。可是FS/GS段寄存器是例外。在计算线性地址时,这两个段寄存器可能被用做额外的基址寄存器(当寻址局部数据或寻址某些操做系统数据结构时)。class

尽管分段机制被禁用了,可是段寄存器加载操做可能致使处理器执行段访问辅助。在这些辅助行为中,启用了分段机制的处理器依然会对被加载的值执行绝大多数的传统检查(即便这些检查对64位模式不起做用)。这样的检查是必要的,由于在64位模式下加载的段寄存器可能被运行在兼容模式的应用程序使用。

在64位模式下,禁用CS/DS/ES/SS/FS/GS的段限长检查。