x86保护模式

处理器架构实际上是不断扩展的,新处理器必须延续旧的设计思路,并保持兼容性和一致性;同时还会有所扩充和增强。

尽管8086是16位的处理器,但它也是32位架构内的一部分。原因在于,32为处理器架构是从8086那里发展来的,是基于8086的,具有延续性和兼容性。

寄存器的扩展

32位处理器在16位处理器的从基础上,扩展了这8个通用寄存器(AX,BX,CX,DX,SI,DI,BP,SP)的长度,使之达到32位。

32位通用寄存器的高16位是不可独立使用的,但低16位保持同16位处理器兼容性。因此,在任何时候他们都可以照往常一样使用。

但是32位处理器并不是16位处理器简单的增强。事实上32位处理器有自己的32位工作模式,而我学习的32模式是32位保护模式。在这种模式下,处理器可以使用它全部的32跟地址线,能够访问4GB内存。

在32位模式下,为了生成32位物理地址,处理器需要使用32位的指令指针寄存器。为此,32位处理器扩展了IP,使之达到32位,工作在32位模式下时使用EIP,但是当工作在16位模式下仍使用IP。

对于32位模式下因为IA-32架构的处理器是基于分段模型,可是32位模式下,对内存的访问从理论上不需要分段,因为它可以自由访问任何一个内存位置。所以引入了平坦模型,即只分一个段,段的基址是0x00000000,段的长度是4GB,在这种情况下视为不分段。

在32位模式下,处理器要求在加在程序时,先定义该程序所拥有的段,然后允许使用这些段。定义段时,除了基地址外,还附加了段界限,特权级别,类型等属性。当程序访问一个段时,处理器将用固件实施各种检查工作,以防止对内存的违规访问。

在32位模式下,传统的段寄存器,如CS,SS,DS,ES,保存的不再是16位段基地址,而是段的选择子(实模式下是段寄存器,在保护模式下就是段选择子,因为在保护模式下他们存储的不再是段地址而是段描述符在描述符表中的索引号),即用于选择要访问的段,除了段选择子外,每个段寄存器还包括一个不可见部分,称为描述符高速缓冲器,里面有段的基地址和各种访问属性。

在保护模式下访问一个段的时候,传送到段选择器的是段选择子。他由三个部分组成,第一部分是索引号,用来在描述符表种选择一个段描述符。T1是描述符表指示器,T1=0时,描述符在GDT中,T1=1时,描述符在LDT中。RPL是请求特权级,表示给出当前选择子的那个程序的特权级

线性地址

我们传统上讲的,段地址个偏移地址称为逻辑地址,偏移地址叫做有效地址,在指令中给出有效地址的方式叫做寻址方式。

然而段的管理是由处理器的段部件负责进行的,段部件将段地址和偏移地址相加,得到访问内存的地址。一般来说,段部件产生的地址就是物理地址。

但是为了解决内存空间碎片化(内存每次分配大小不定,时间长后会产生过多过小的内存空间块),IA-32处理器支持分页功能,分页功能将物理内存空间划分成逻辑上的页。通过使用页,可以简化内存管理。

当页功能开启时,段部件产生的地址就不再是物理地址了,而是线性地址,线性地址还要经过页部件转换后,才是物理地址。

线性地址的概念用来描述任务的地址空间。IA-32处理器上的每个任务拥有4GB的虚拟内存空间,这是一段长4GB的平坦空间,就像一段平直的线段。相应的,由段部件产生的地址,就对应着线性地址空间上的每一个点,这就是线性地址。

全剧描述符表

在保护模式下,对内存的访问仍能使用段地址和偏移地址,但是,在每个段能够访问之前,必须先进行登记。当你访问的偏移量超出段的界限时,处理器就会阻止这种访问,并产生一个叫做内部异常的中断。

断描述符,用八个字节来描述一个段有关的信息。为了存放这些描述符,需要在内存中开辟一段空间,在这段空间里,所有的描述符都是挨在一起,集中存放的,这就形成了一个描述符表。

最主要的描述符表是全局描述符表(GDT),在进入保护模式前,必须要定义全局描述符表。

图品出自

为了跟踪全局描述符表,处理器内部有一个48位的寄存器,称为全局描述符表寄存器(GDTR)。该寄存器高32为存放全局描述符表线性基地址,低16位存放全局描述符表边界。

因为GDT的界限是16位所以表的大小最多是2^16字节(64KB),又因为全局描述符大小为8字节,所以最多可以定义8192个描述符。

虽说基地址有32位,但是由于在进入保护模式之后,处理器立即要按新的内存访问模式工作,所以,必须在进入保护模式之前定义GDT。但是,由于在实模式下只能访问1MB的内存,故GDT通常都定义在1MB以下的范围内。也允许在进入保护模式之后换位置重新定义GDT。

段描述符中的段属性也被安排在两个域中。下面对其定义及意义作说明。

(1)G为就是段界限粒度(Granularity)位

G=0表示界限粒度为字节;G=1表示界限粒度为4K 字节。注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位。

(2)D/B位是一个很特殊的位在描述可执行段、向下扩展数据段或由SS寄存器寻址的段(通常是堆栈段)的三种描述符中的意义各不相同

在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大小。

D=1表示默认情况下指令使用32位地址及32位或8位操作数,这样的代码段也称为32位代码段;

D=0 表示默认情况下,使用16位地址及16位或8位操作数,这样的代码段也称为16位代码段,它与80286兼容。可以使用地址大小前缀和操作数大小前缀分别改变默认的地址或操作数的大小。

在向下扩展数据段的描述符中,D位决定段的上部边界。

D=1表示段的上部界限为4G;

D=0表示段的上部界限为64K。

在描述由SS寄存器寻址的段描述符中,D位决定隐式的堆栈访问指令(如PUSH和POP指令)使用何种堆栈指针寄存器。

D=1表示使用32位堆栈指针寄存器ESP;

D=0表示使用16位堆栈指针寄存器SP。

(3)AVL位是软件可利用位

80386对该位的使用未做规定,此位被linux和windows操作系统忽略。

(4)P位称为存在(Present)位

P=1表示描述符对地址转换是有效的,或者说该描述符所描述的段存在,即在内存中;P=0表示描述符对地址转换无效,即该段不存在。使用该描述符进行内存访问时会引起异常。

(5)DPL表示描述符特权级(Descriptor Privilege level)

共2位。它规定了所描述段的特权级,用于特权检查,以决定对该段能否访问。

(6)DT位说明描述符的类型

对于存储段描述符而言,

DT=1,以区别与系统段描述符和门描述符(DT=0)。

(7)TYPE说明存储段描述符所描述的存储段的具体属性

其中的位0指示描述符是否被访问过(Accessed),用符号A标记。

A=0表示尚未被访问,

A=1 表示段已被访问,

当把描述符的相应选择子装入到段寄存器时,80386把该位置为1,表明描述符已被访问,操作系统可测试访问位,已确定描述符是否被访问过。

此为位1,对应的type为奇数,因此type对应的数值为奇数时标识该描述符被访问过,否则为偶数标识未被访问过(可从前面的表中看出)

综上我们可以看到在类型不同时,段描述符的区别之处,如下所示

代码段描述符

表示这个段描述符代表一个代码段,它可以放在GDT中。该描述符置S标志为1。

数据段描述符

表示这个段描述符代表一个数据段,它可以放在GDT中,该描述符置S标志为1。

任务状态段描述符

表示这个段描述符代表一个任务状态段,也就是说这个段用于保存处理器寄存器的内容。它只能出现在GDT中,根据相应的进程是否正CPU上运行,其Type字段的值分别为11或9。这个描述符的S标志置为0。

时间: 2024-10-10 07:22:08

x86保护模式的相关文章

x86保护模式笔记

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 以下为自己的总结的x86保护模式知识 --------------------------------------------

程序的加载和执行(六)——《x86汇编语言:从实模式到保护模式》读书笔记26

程序的加载和执行(六)--<x86汇编语言:从实模式到保护模式>读书笔记26 通过本文能学到什么? NASM的条件汇编 用NASM编译的时候,通过命令行选项定义宏 Makefile的条件语句 在make命令行中覆盖Makefile中的变量值 第13章习题解答 复习如何构造栈段描述符 我们接着上篇博文说. 在我修改后的文件中,用到了条件汇编. 比如: %ifdef DEBUG put_core_salt: ;打印内核的符号 ... ... put_usr_salt: ;打印用户的符号 ... .

《X86汇编语言 从事模式到保护模式》问题

书中的42页,监测点4.2第一题,代码如下: mov ax, 0xb800 mov ds, ax mov [0x00], 'a' mov [0x02], 's' mov [0x04], 'm' jmp $ 编译会报错 提示没有指定操作数长度,修改后为 mov ax, 0xb800 mov ds, ax mov byte [0x00], 'a' mov byte [0x02], 's' mov byte [0x04], 'm' jmp $ 然后用书中提供的工具fixvhdwr.exe写入到虚拟机的

程序的载入和运行(五)——《x86汇编语言:从实模式到保护模式》读书笔记25

程序的载入和运行(五)--<x86汇编语言:从实模式到保护模式>读书笔记25 前面几篇博文最终把代码分析完了.这篇就来说说代码的编译.运行和调试. 1.代码的编译及写入镜像文件 之前我们都是在命令行输入命令进行编译和写入.源文件少的时候还不认为麻烦,当源文件多了,就会认为特别麻烦.有没有简单的方法呢? 当然有,就是用make工具. 1.1.什么是make工具 make是一个命令工具,它解释Makefile中的指令.在Makefile文件里描写叙述了整个project全部文件的编译顺序.编译规则

存储器的保护(一)——《x86汇编语言:从实模式到保护模式》读书笔记18

本文是原书第12章的学习笔记. 说句题外话,这篇博文是补写的,因为让我误删了,可恶的是CSDN的回收站里找不到! 好吧,那就再写一遍,我有坚强的意志.司马迁曰:“文王拘而演<周易>:仲尼厄而作<春秋>:屈原放逐,乃赋<离骚>:左丘失明,厥有<国语>:孙子膑脚,<兵法>修列:不韦迁蜀,世传<吕览>……”好了,不煽情了,进入正题. 第12章的代码如下. 1 ;代码清单12-1 2 ;文件名:c12_mbr.asm 3 ;文件说明:硬盘主引

存储器的保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记20

存储器的保护(三) 改动本章代码清单,使之能够检測1MB以上的内存空间(从地址0x0010_0000開始,不考虑快速缓存的影响).要求:对内存的读写按双字的长度进行.并在检測的同一时候显示已检測的内存数量.建议对每一个双字单元用两个花码0x55AA55AA和0xAA55AA55进行检測. 上面的文字选自原书第12章的习题1. 这篇博文就讨论一下这道题.由于是初学,我不正确自己做太高的要求.仅仅要实现功能就可以. 代码清单 ;文件说明:第12章习题-1 ;创建日期:2016-3-7 ;------

《X86汇编语言 从实模式到保护模式》bochs 配置教程(详细)

本文是写给<X86汇编语言 从实模式到保护模式>读者的一份Bochs配置指南. 我们要做的有: 1.下载并安装bochs 2.配置bochs 3.通过bochs调试虚拟硬盘 bochs的官方网址:http://bochs.sourceforge.net/ bochs的下载地址:http://sourceforge.net/projects/bochs/files/bochs/ 本书附带文件下载地址:https://files-cdn.cnblogs.com/files/leec/booktoo

ASM:《X86汇编语言-从实模式到保护模式》第12章:存储器的保护

12章其实是11章的拓展,代码基本不变,就是在保护模式下展开讨论. ★PART1:存储器的保护机制 1. 修改段寄存器的保护 当执行把段选择子传到段寄存器的选择器部分的时候,处理器固件在完成传送之前,要检查和确认选择子是正确的,并且该选择子选择的描述符也是正确的.假如索引号是正确的,也就是说明索引号8+7要小于等于边界.如果超过边界,那么处理器就会终止处理,产生异常中断13,同时段寄存器的原值保持不变. 同时处理器还要对描述符的类别进行检查,如果描述符的类别进行确认,举个例子来说,如果描述符的类

CPU 实模式 保护模式 和虚拟8086模式

从80386开始,CPU有三种工作方式:实模式,保护模式和虚拟8086模式.只有在刚刚启动的时候是real-mode,等到操作系统运行起来以后就切换到protected-mode.实模式只能访问地址在1M以下的内存称为常规内存,我们把地址在1M 以上的内存称为扩展内存.在保护模式下,全部32条地址线有效,可寻址高达4G字节的物理地址空间; 扩充的存储器分段管理机制和可选的存储器分页管理机制,不仅为存储器共享和保护提供了硬件支持,而且为实现虚拟存储器提供了硬件支持; 支持多任务,能够快速地进行任务