前言
所谓“保护模式”,重点是“保护”,可保护的是什么呢?答案是:内存中的数据与代码。有几种保护手段呢?段保护与页保护。这篇文章我尝试结合intel手册来重新梳理一下intel保护模式中的段保护有关机制。
保护模式的两种保护机制
The memory management facilities of the IA-32 architecture are divided into two parts: segmentation and paging. Segmentation provides a mechanism of isolating individual code, data, and stack modules so that multiple programs (or tasks) can run on the same processor without interfering with one another. Paging provides a mechanism for implementing a conventional demand-paged, virtual-memory system where sections of a program’s execution environment are mapped into physical memory as needed. Paging can also be used to provide isolation between multiple tasks. When operating in protected mode, some form of segmentation must be used. There is no mode bit to disable segmentation. The use of paging, however, is optional.
上面是intel卷三 3.1节 关于“保护模式内存管理”的摘要,注意黑体和下划线部分,intel明确指出其内存管理被分成两部分,段式管理(segmentation)和页式管理(paging)。另外,段式管理是必须强制选用的,而页式管理是可选的。
如下图,是intel说明的保护模式内存管理机制。其首先通过段保护确定具体的线性内存地址,然后通过页保护来确定对应的物理地址。其实在有关资料中很多人都注重Intel的分页机制而忽视分段机制,我猜想很可能是因为各个段的Base都为零,不容易觉察到段保护的存在,段更重要的是其权限检查机制。
段描述符
一个段由其段描述符所描述,其不同的段类型存在不同的段描述符,但其可以认为由三部分组成:段权限(Access),段机制(Base),段线程(Limit)。
当然,因为其历史遗留问题,其实际的段描述符数据结构往往相当难看,是为了兼容有关结构体,如下图。
段描述符分为类,系统段描述符和代码-数据段描述符(其由S位),其中系统段描述符分为分为六类,存储在LDT或GDT表中。值得注意的是,要区分段描述符与门描述符,门描述存储在IDT表中,门描述符中存储着段选择子,通过段选择子可以从GDT/LDT表中找到段描述符。
段寄存器
CPU通过段寄存器来管理段描述符,比如我们如果调用汇编指令 "mov [0x1100],eax",其隐含着 "ds:[0x1100]",该ds就是段寄存器。
段寄存器由两部分组成: