没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
第一章.概述
1.1 80386 保护模式简介
本章的主要内容是介绍 80386 保护模式。
1. 保护模式简介
Intel 推出 x86 架构已近 30 年,刚开始推出的 8086 处理器是一款 16 位的处理器,它标
志着 x86 架构的诞生,这种 16 位处理器数据总线是 16 位的,而地址总线是 20 位的,最多
可以寻址 1MB 的地址空间。之后的 80286 处理器也是 16 位,但是地址总线有 24 位,而且
从 80286 开始 CPU 演变出两种工作模式:实模式和保护模式;而 80386 则是 Intel 推出的 80x86
系列中的第一款 32 位处理器,它的数据总线与地址总线都是 32 位,可以寻址 4G 的地址空
间;AMD 公司随后在 2000 年又在 x86 架构的基础上推出了 x86-64 处理器架构,AMD 的处
理器可以兼容 32 位的指令集,所以它既是 64 位的又是 32 位的。
在 x86 架构中,16 位的处理器与 32 位处理器所对应的寄存器是有所不同的。像 8086
寄存器组就分为通用寄存器、专用寄存器和段寄存器三类总共 15 个,其中通用寄存器有 AX、
BX、CX、DX、SP、BP、DI 及 SI,专用寄存器包括 IP、SP 和 FLAGS 三个
16 位寄存器,
而段寄存器则有 CS、DS、SS、ES,这些寄存器都是 16 位的。32 位 x86 架构对应的寄存器
则共有 34 个,其中包括 EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP 8 个 32 位的通用
寄存器;6 个 16 位的段寄存器 CS、DS、SS、ES、FS、GS,相比 8086 增加了 FS 和 GS;
GDTR、LDTR、IDTR 和 TR 四个系统地址寄存器;EFLAGS、EIP、CR0---CR3 6 个状态和
控制寄存器,在这里标志寄存器 EFLAGS 与指令指针寄存器 EIP 都从 16 位进化到了 32 位;
还有就是增加了一些调试寄存器、段描述符寄存器以及测试寄存器。
表 1-18086 和 86386 的寄存器的对比
8086 的寄存器 80386 的寄存器
通用寄存
器
AX、BX、CX、DX、SP、
BP、DI、SI
EAX、EBX、ECX、EDX、ESI、EDI、EBP、
ESP
段寄存器
CS、DS、SS、ES CS、DS、SS、ES、FS、GS
段描述符
寄存器
无 对程序员不可见
状态和控
制寄存器
FLAGS 、IP EFLAGS、EIP、CR0、CR1、CR2、CR3
系统地址
寄存器
无 GDTR、IDTR、TR、LDTR
调试寄存
器
无 DR0--DR7
测试寄存
器
无 TR0--TR7
保护模式(Protected Mode) 是一种和 80286 系列及之后的 x86 兼容 CPU 操作模
式。保护模式有一些新的特色,设计用来增强多功能和系统稳定度,比如内存保护、
分页、系统以及硬件支持的虚拟内存。大部分的现今 x86 操作系统都在保护模式下
运行,包含 Linux、FreeBSD、以及 微软 Windows 2.0 和之后版本。需要指出的是,
保护模式在增加这些新特性的同时,也带来了系统软件设计的复杂性
在 8086 时代,CPU 中设置了四个段寄存器:CS、DS、SS 和 ES,分别用于可执
行代码段、数据段以及堆栈段。每个段寄存器都是 16 位的,对应于地址总线中的高
16 位。每条“访存”指令中的内部地址也都是 16 位的,但是在送到地址总线之前,
CPU 内部会自动地把它与某个段寄存器中的内容相加。因为段寄存器中的内容对应于
20 位地址总线中的高 16 位(也就是把段寄存器左移 4 位),所以相加时实际上是地址
总线中的高 12 位与段寄存器中的 16 位相加,而低 4 位保留不变,这样就形成一个 20
位的实际地址,也就实现了从 16 位内存地址到 20 位实际地址的转换,或者叫“映射”。
段式内存管理带来了显而易见的优势:程序的地址不再需要采用内存物理地址进
行编码了,调试错误也更容易定位了,更可贵的是支持更大的内存地址,程序员开始
获得了自由。 然而,8086 系统很难从硬件层面对软件系统进行保护,在该环境下,
应用程序可以直接对系统的任意内存地址(包括操作系统所在的区域)进行操作,所
以该系统的安全漏洞几乎是显而易见的。
到了 80286 时代,它的地址总线位数增加到了 24 位,因此可以访问到 16MB 的
内存空间。更重要的是从此开始引进了一个全新理念——保护模式。这种模式下内存
段的访问受到了限制。访问内存时不能直接从段寄存器中获得段的起始地址了,而需
要经过额外转换和检查。为了和 8086 兼容,80286 内存寻址可以有两种方式,一种是
先进的保护模式,另一种是老式的 8086 方式,被称为实模式。Intel 选择了在段寄存
器的基础上构筑保护模式,并且保留 16 位的段寄存器。不同的是,在保护模式下,
段范围不再受限于 64K,可以达到 16MB
(或者 80386 的 4GB)。这一下真正解放了
软件工程师,他们不必再费尽心思去压缩程序规模,软件功能也因此迅速提升。
从 8086 的 16 位到 80386 的 32 位,看起来是处理器位数的变化,但实质上是处
理器体系结构的变化,从寻址方式上说,就是从“实模式”到“保护模式”的变化。
下面,我们详细讨论保护模式的引入带来的寻址方式、中断管理这两个方面的变化,
以及相关的模式切换以及安全性问题。
2. 寻址方式的变化
1) 实模式下段的管理
实模式采用 16 位寻址模式,在该模式中,最大寻址空间为 1MB,最大分段为 64KB。
由于处理器的设计需要考虑到向下兼容的问题,实模式也是我们今天接触到的大多数计算机
在启动后处于的寻址模式。
8086 处理器地址总线扩展到 20 位,但算术逻辑运算单元(ALU)宽度即数据总线却只
有 16 位,也就是说直接参与运算的数值都是 16 位的。为支持 1MB 寻址空间,8086 在实模
式下引入了分段的方法。在处理器中设置了四个 16 位的段寄存器:CS、DS、SS、ES,对
应于地址总线中的高 16 位。寻址时,采用以下公式计算实际访问的物理内存地址:
实际物理地址 = (段寄存器 << 4) + 偏移地址
这样,便实现了 16 位内存地址到 20 位物理地址的转换。
例如,这样的一句汇编代码:MOV AX,ES:[1200H]。在这里程序表示的意思是将
ES:[1200H]所指向的内存空间里的 16 位数据复制到 AX 寄存器中。ES 是指定的段寄存器,
而 1200H 则是偏移量,假设寄存器 ES 中的值为 1000H,则根据以上的物理地址计算公式,
得到的实际访问地址为 11200H。
我们回顾一下实模式下程序的运行。程序运行的实质就是指令的执行,显然 CPU 是指
令得以执行的硬件保障,而 CPU 是如何知道指令在什么地方呢?80x86 系列是使用 CS 寄存
器配合 IP 寄存器的组合来通知 CPU 指令在内存中的位置。程序指令在执行过程中一般还需
要有各种数据,80x86 系列有 DS、ES、FS、GS、SS 等用于指示不同用途的数据段在内存
中的位置。程序可能需要调用系统的服务子程序,80x86 系列使用中断机制来实现系统服务。
总的来说,这些就是实模式下一个程序运行所需的主要内容。
我们再来回顾一下实模式下的寻址方式。寻址方式一共有以下 8 种:
1. 立即数寻址 例如:MOV AX, 1234H
2. 寄存器寻址 例如:MOV AX, BX
3. 直接寻址 例如:MOV AX, [1234H]
4. 寄存器间接寻址 例如:MOV AX, [BX]
5. 基址寻址 例如:MOV AX, [BX+100H]
6. 变址寻址 例如:MOV AX, [SI+100H]
7. 基址加变址寻址 例如:MOV AX, [BX+SI]
8. 带位移的基址加变址寻址 例如:MOV AX, [BX+SI+100H]
纵然有这么多种的寻址方式,但实际上实模式的寻址本质上都是段基址左移 4 位加上
偏移得到物理地址,如图 1-1 所示:
段基址
XXXX XXXX XXXX XXXX
15
0
XXXX XXXX XXXX XXXX
015
0000
0000
偏移地址
+
XXXX XXXX XXXX XXXX XXXX
019
物理地址
=
图 1-1 实模式的寻址
2) 保护模式下段的管理
保护模式的段式寻址相对于实模式而言较为复杂一些。在保护模式下,分段机制是利
用一个称作段选择子的偏移量到全局描述符表中找到需要的段描述符,而这个段描述符中就
存放着真正的段的物理首地址,然后再加上偏移地址量便得到了最后的物理地址。需要指出
的是,在 32 位平台上,段物理首地址和偏移址都是 32 位的,实际物理地址的计算不再需要
将段首地址左移 4 位了,直接相加即可,如果发生溢出的情况,则将溢出位舍弃。
在这里出现了两个新的词汇:段选择子、描述符。我们可以这样理解这个寻址过程,
首先有一个结构体类型(称为段描述符,Descriptor),它有三个成员变量:段物理首地址、
段界限、段属性,在内存中存在一个数组(称为全局描述符表,Global Descriptor Table)维
护一组这样的结构体。段选择子(Selector)中存储的是对应的结构体在该数组中的下标,
也就是索引,通过该索引从数组中找到对应的结构体,从而得到段的物理首地址,然后加上
偏移量,得到真正的物理地址。
一般保护模式段式寻址可用 xxxx:yyyyyyyy 表示。其中 xxxx 表示索引,也就是段选
择子,是 16 位的;yyyyyyyy 是偏移量,是 32 位的。到哪里去寻找全局描述符表呢?80386
以及以后的处理器专门设计了一个寄存器 GDTR(Global Descriptor Table Register),专门用
于存储全局描述符表在内存中存放的位置,当发生内存寻址与定位的时候,处理器通过该寄
存器找到全局描述符表,并通过 xxxx 找到对应的描述符,进而得到该段的起始地址,并加
上 yyyyyyyy 得到最终的物理地址。这个过程可以用图示 1-2 来描述。
0x00000000
0xFFFFFFFF
段描述符
描述符表
线性地址空间
GDTR
数据段
数据
段选择子 : 偏移量
图 1-2 保护模式段式寻址
GDTR 寄存器有 48 位,其中有 32 位记录描述附表的物理地址,16 位记录全局描述符
表的长度(该表占据的物理内存字节数),如图 1-3 所示。
BYTE4
描述符表物理地址 31…0
BYTE3 BYTE2
描述符表长(字节
数) 15…0
BYTE1 BYTE0
BYTE5
图 1-3 GDTR 位分布图
再来看看段描述符,段描述符实际上是一个占据 64 位内存(8 个字节)的结构体,如
图 1-4 所示。
段基址
31…24
BYTE7
BYTE6
属性
BYTE5 BYTE4
段基址 23…0
BYTE3 BYTE2
段限长 15…0
BYTE1 BYTE0
BYTE6 BYTE5
7 6 5 4
G D/B 0 AVL
段限长19…16
P DPL S TYPE
012345671 023
图 1-4 段描述符的结构
一个 64 位的段描述符包含了段的物理首地址、段的界限以及段的属性。在描述符中,
段基址占 32 位,段限长占 20 位,属性占 12 位。
由图 1-4 可知,段基址为 2,3,4,7 字节,共 32 位。段限长为 0,1 以及 6 字节的低
四位,共 20 位,段限长即段最大长度,与属性 G 共同确定。G = 0 时描述符中的 20 位段限
长为实际段限长,最大限长为 1MB(0-FFFFFh)。G = 1 则 32 位段限长为描述符中的 20
位乘以 4KB,即段限长左移 12 位后加上 FFFH,最大限长为 4GB。可以看到,段首址的低
24 位被存放在第 2、3、4 号字节中,而高 8 位则存放在第 7 号字节中,将这四个字节合并
便可以得到完整的段首地址。
下面我们将结合图 1-4 详细介绍一下段描述符中的段属性。
G:段限长粒度,G = 0 时,粒度为 1B,G = 1 时,粒度为 1 页(4KB)。
D/B:对于不同类型段含义不同。在可执行代码段中,这一位叫做 D 位,D = 1 使用 32
位地址和 32/8 位操作数,D = 0 使用 16 位地址和 16/8 位操作数。在向下扩展的数据段中,
这一位叫做 B 位,
B = 1 段的上界为 4GB,B = 0 段的上界为 64KB。在描述堆栈段的描述符
中,这一位叫做 B 位,B = 1 使用 32 位操作数,堆栈指针用 ESP,B = 0 使用 16 位操作数,
堆栈指针用 SP。
AV L :Available and Reserved Bit,通常设为 0。
P:存在位,P = 1 表示段在内存中。
DPL:描述符特权级,取值 0 ~ 3 共 4 级。0 特权级为最高,而 3 特权级为最低,表示
访问该段时 CPU 所需处于的最低特权级,我们在后面会详细讨论特权级的问题。
S:描述符类型标志,S = 1 表示代码段或者数据段;S = 0 表示系统段(TSS、LDT)和
门描述符。
TYPE:描述符类型,和 S 结合使用,可以表示的描述符类型有:代码段、数据段、TSS、
LDT、中断门(Interrupt Gate)、陷阱门(Trap Gate)、调用门(Call Gate)、任 务 门( Task Gate)
其中,根据描述符类型标志 S 和 TYPE 可以确定描述符的类型。
当 S = 1 时,TYPE < 8 时,为数据段描述符。数据段都是可读的,不一定可写。如下表
1-2 所示:
1.2 描述符类型——数据段描述符
TYPE
说明
十进制值
EWA
数据段
0 0 0 0 0
只读
1 0 0 0 1
只读,已访问
2 0 0 1 0
读/写
3 0 0 1 1
读/写,已访问
4 0 1 0 0
只读,向下扩展
5 0 1 0 1
只读,向下扩展,已访问
6 0 1 1 0
读/写,向下扩展
7 0 1 1 1
读/写,向下扩展,已访问
当 S = 1 时,TYPE ≥ 8时,为代码段描述符。代码段都是可执行的,一定不可写。如
下表 1.3 所示:
1.3 描述符类型——代码段描述符
TYPE
说明
十进制值
C R A
代码段
8 1 0 0 0
只执行
9 1 0 0 1
只执行,已访问
10 1 0 1 0
执行/读
11 1 0 1 1
执行/读,已访问
剩余137页未读,继续阅读
资源评论
元口
- 粉丝: 52
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功