浅析Intel处理器体系结构:分段机制

文章目录

    • 概述
      • 地址类型
    • 实地址模式下的分段机制
      • 段类型
    • 32位保护模式下的分段机制
      • 段描述符表
      • 段描述符
        • 代码段描述符
        • 数据段描述符
        • 系统段描述符类型
      • 段选择子
    • 64位模式下的分段机制
    • 相关参考

概述

分段机制的本质是把地址空间的内存组织成一些长度可变的内存块单元。在早期8086处理器时代,Intel为了实现寻址1MB地址空间的能力,提出了分段机制。在后续处理器演进中,为了保持向后兼容,Intel在32位保护模式中继续采用分段机制,但包括Linux在内的各种操作系统实现都只使用了平坦地址模型,并未真正使用到分段机制,至发展到64位架构时,处理器硬件也不再关心段基址信息,分段机制名存实亡。

地址类型

在进一步说明分段机制之前,需要先了解Intel处理器中涉及的几种地址类型:

  • 逻辑地址:由分段机制引出的地址概念,其由段基地址+段内偏移地址两部分组成。逻辑地址最终都会转换为虚拟地址,但在不同运行模式下转换过程各不相同;
  • 线性地址:由逻辑地址中的段基地址+段内偏移地址转换而成。如果将段基地址配置成0,段内偏移地址覆盖整个线性地址空间就成了平坦地址,平坦地址是一种特殊的线性地址,比较贴近于我们平常所说的虚拟地址。
  • 物理地址:真实存在于硬件设备上,它通过处理器的引脚直接或间接地与外部设备、RAM、ROM相连接。在处理器开启分页机制的情况下,线性地址需要经过页表映射才能转换成物理地址;否则,线性地址将直接映射成物理地址。

实地址模式下的分段机制

早期8086处理器设计有20位的地址总线,理论可寻址1MB的地址空间,但8086是16位处理器,内部寄存器只有16位,只能寻址64KB的地址空间。为了解决16位处理器实现20位寻址的问题,8086处理器将整个存储空间划分成了多个逻辑段,然后通过段地址:偏移地址(逻辑地址)组合的方式来计算最后内存单元的物理地址,计算公式如下:

	物理地址 = 段地址 << 4 + 偏移地址

段类型

8086处理器将逻辑段划分成了4种类型,分别是代码段、数据段、附加段和堆栈段,并使用约定的段寄存器进行存储,如下:

  • 代码段:用于存放指令,段基址存放在段寄存器CS;
  • 数据段:用于存放数据,段基址存放在段寄存器DS;
  • 附加段:用于辅助存放数据,段基址存放在段寄存器ES;
  • 堆栈段:用于堆栈使用,段基址存放在段寄存器SS。

32位保护模式下的分段机制

进入32位处理器时代后,Intel处理器沿用了分段的概念,但分段的具体实现与实地址模式有很大的差别。32位保护模式下的逻辑地址仍然由一个段部分和一个偏移地址部分构成,但段部分不直接存储段基址,而是存放一个指向段描述表中某个段描述符的索引。Intel处理器使用段描述符来描述一个段的信息,包括段基址、段限长以及段属性等信息,并存储在系统内存的段描述表中,可以通过cs/ds/ss等寄存器存储的段选择子索引描述表中的一个段描述符来指定相应的段。如下是32位保护模式地址转换示意:
浅析Intel处理器体系结构:分段机制_第1张图片
为了把逻辑地址转换成一个线性地址,处理器执行一下操作:

  1. 使用段选择符索引在GDT或LDT表中对应的段描述符;
  2. 利用段描述符属性字段检查段的访问权限和范围,以确保该段是可访问的,并且偏移量位于段界限内;
  3. 把短描述符中取的段基地址加到偏移量上,最后形成一个线性地址。

得到线性地址后,是否可以直接作为物理地址使用,则取决于处理器有没有开启分页机制。接下来对分段涉及的数据结构进行说明。

段描述符表

段描述表是存储段描述符的一个数组,描述符表的长度可变,最多可以包含8192个8字节描述符。Intel处理器定义了两种描述符表:

  • 全局描述符表GDT
  • 局部描述符表LDT
    浅析Intel处理器体系结构:分段机制_第2张图片

段描述符

段描述符是GDT和LDT表中的一个数据结构项,用于向处理器提供一个段的基地址、长度以及访问控制状态等信息。每个段描述符长度是8字节,含有三个主要字段:段基地址、段限长和段属性,各个字段的含义如下:

  • 段基地址:指定段在线性地址空间中的开始地址;
  • 段限长:段内最大可用偏移量,定义了段的长度;
  • 段属性:描述段的属性,例如是否可读写、是否可执行以及特权级等

段描述符的通用格式如下:
浅析Intel处理器体系结构:分段机制_第3张图片
段描述符中的Type字段指定段描述符的类型,大致可分为三类:代码段描述符、数据段描述符和系统段描述符。
浅析Intel处理器体系结构:分段机制_第4张图片

代码段描述符

数据段描述符

系统段描述符类型

当段描述符中的S标志(描述符类型)是复位状态0,那么该描述符是一个系统描述符。系统段描述符支持以下一些类型:

  • 局部描述符表的描述符;
  • 任务状态段TSS描述符;
  • 调用门描述符;
  • 中断门描述符;
  • 陷阱门描述符;
  • 任务门描述符。

段选择子

段选择子是段的一个16位标识符,用于索引段描述符表中的段描述符,格式如下;
浅析Intel处理器体系结构:分段机制_第5张图片
段选择子包含三个字段:

  • 请求特权级RPL:提供段保护信息;
  • 表索引标志TI:指示索引的段描述符表是GDT/LDT。TI=0标识描述符在GDT中;TI=1标识描述符在LDT中;
  • 索引值:描述符在GDT或LDT表的索引。

64位模式下的分段机制

64位模式下,段描述表可容纳8192个8字节的描述符表项。系统描述符扩展至16个字节,占用两个表项的空间,包括:

  • 调用门描述符;
  • 中断门描述符;
  • 局部描述符表的描述符;
  • 任务状态段TSS描述符。

另外,64位模式下,处理器不再关心段描述符的段基地址和段限长字段,段描述符会强制将段基地址和段限长覆盖到整个线性地址空间,因此分段机制其实已经名存实亡。

相关参考

  • 《Intel处理器手册》
  • 《Linux内核完全注释》

你可能感兴趣的:(#,Intel体系结构,x86,处理器,CPU)