【x86汇编语言:从实模式到保护模式笔记】第十一章 进入保护模式

本章目标:

1、了解x86处理器的保护模式需要先定义全局描述符表GDT,认识段描述符的各个组成部分以及它们的含义和作用。
2、认识32位处理器的全局描述符表寄存器GDTR、段寄存器(由段选择器和描述符高速缓存器组成)、控制器CR0和段选择子。
3、了解进入32位保护模式的方法和步骤。
4、学习保护模式下的一些程序调试技术,如查看全局描述符表GDT、段寄存器和控制寄存器等。
5、学习lgdt指令

11.1 代码清单

11.2 全局描述符

  • 段描述符:保存段的相关信息,包括段基地址以及段界限,8个字节。
  • 全局描述符表(Global Descriptior Table,GDT):一系列段描述符在内存空间中的连续排列。进入保护模式前,必须要定义全局描述符表。
  • 全局描述符表寄存器(GDTR):定义了全局描述符表的范围。GDTR的32位线性地址部分保存的是全局描述符在内存中的起始线性地址,16位边界部分保存的是全局描述符表的边界,其在数值上等于表的大小(总字节数)减一。

【x86汇编语言:从实模式到保护模式笔记】第十一章 进入保护模式_第1张图片

GDT通常都定义在1MB一下的内存范围中,当然,允许在进入保护模式之后换个位置重新定义GDT。

11.3 存储器的段描述符

描述符不是由用户自己建立的,而是在加载时,由操作系统根据你的程序结构而建立的,而用户程序通常是无法建立和修改GDT的。
【x86汇编语言:从实模式到保护模式笔记】第十一章 进入保护模式_第2张图片

  • 32位段基地址和32位段界限
    对于向上扩展的段,如代码段和数据段来说,偏移量是从0开始递增的,段界限决定了偏移量的最大值;对于向下扩展的段,如栈段来说,段界限决定了偏移量的最小值。

  • G
    G是粒度位(Granularity),用于解释段界限的含义。
    当G位是“0”时,段界限以字节为单位。相反,如果该位是“1”,那么,段界限是以4KB为单位的。

  • S
    S位用于指定描述符的类型(Descriptor Type)。
    当S位是“0”时,表示是一个系统段;为“1”时,表示是一个代码段或者数据段(栈段也是特殊的数据段)。

  • DPL
    DPL表示描述符的特权级(Descriptor Privilege Level,DPL)。这两位用于指定段的特权级。共有4种处理器支持的特权级别,分别是0、1、2、3。其中0是最高特权级别,3是最低特权级别。该字段用于指定要访问该段的程序所必须具有的最低特权级别。

  • P
    P是段存在位(Segment Present)。P位用于指示描述符所对应的段是否存在。类似虚拟内存中页表的有效位。

  • D/B
    D/B位是“默认的操作数大小”(Default Operation Size),设立该标志位,主要是为了能够在32位处理器上兼容运行16位保护模式的程序。
    对于代码段,此位称做“D”位,用于指示指令中默认的偏移地址和错作数尺寸。D=0表示16位(使用IP寄存器取指),D=1表示32位(使用EIP寄存器取指)。
    对于数据段,此位称做“B”位,用于指示在进行隐式的栈操作时(push,pop,call),是使用SP还是ESP寄存器。

  • L
    L位是64位代码段标志(64-bit Code Segment),保留此位给64位处理器使用。

  • TYPE
    TYPE字段共4位,用于指示描述符的子类型,或者说是类别。
    【x86汇编语言:从实模式到保护模式笔记】第十一章 进入保护模式_第3张图片

  • AVL
    AVL是软件可以使用的位(Available),通常由操作系统来用。

11.4 安装存储器的段描述符并加载GDTR

解释代码11~38行,定义GDT中的描述符。
处理器规定,GDT中的第一个描述符必须是空描述符,或者叫哑描述符或NULL描述符。

lgdt指令

加载描述符表的线性基地址和界限到GDTR寄存器。

lgdt m48       ;lgdt m16&m32
;将48位的内存区域加载到GDTR寄存器中

11.6 保护模式下的内存访问

  • CR0寄存器:控制两种模式的开关
    CR0是32位寄存器,它的第1位(位0)是保护模式允许位(Protection Enable,PE),置“1”,则处理器进入保护模式。
    【x86汇编语言:从实模式到保护模式笔记】第十一章 进入保护模式_第4张图片

  • 段寄存器
    32位段寄存器分为2部分,前16位和8086相同,每个段寄存器还包括一个不可见的部分,称为描述符高速缓存器,用来存放段的线性地址、段界限和段属性。
    【x86汇编语言:从实模式到保护模式笔记】第十一章 进入保护模式_第5张图片

  • 段选择子
    【x86汇编语言:从实模式到保护模式笔记】第十一章 进入保护模式_第6张图片

实模式内存访问
  • 16位:访问内存用的是逻辑地址,即将段地址乘以16,再加上偏移地址。
  • 32位:每当引用一个段时,处理器自动将段地址左移4位,并传送到描述符高速缓存器。此后,就一直使用描述符高速缓存器的内容作为段地址。所谓引用一个段,就是执行将段地址传送到段寄存器的指令,如jmp
保护模式内存访问

每当引用一个段时,段寄存器就会根据传入的段选择子中的描述符索引,从GDT表中将描述符索引对应的描述符中的线性基地址、段界限和段的访问属性,加载到描述符高速缓存器中。
此后每当有访问内存的指令时,就不再访问GDT中的描述符,直接用当前段寄存器描述符高速缓存器提供线性基地址。

11.7 清空流水线并串行化处理

设置完CR0寄存器的PE位之后,需要立即用jmp或者call转移到当前指令流的下一条指令上。

11.8 保护模式下的栈

11.8.1 关于栈段描述符中的界限值

段内偏移的最小值是界限值和粒度的乘积加一。

ESP > 界限值 x 粒度值

你可能感兴趣的:(Linux,linux)