计算机原理学习(7)-- x86-32 CPU和内存管理之分段管理

前言

 

前一篇我们介绍了内存管理中的分页试内存管理,分页的主要作用就是使得每个进程有一个独立的,完整的内存空间,通过虚拟内存技术,使得程序可以在较小的内存上运行,而进程之间内存空间相互独立,提高了安全性。这一篇将主要介绍内存管理中分段管理,以及两种的结合,也是目前计算机普遍采用的段页式内存管理。这也直接决定了的后面程序的编译,加载以及允许时的内存布局。

 

 

 

1. 内存分段

 

 

1.1 为什么分段?

 

 

在x86-16体系中,为了解决16位寄存器对20位地址线的寻址问题,引入了分段式内存管理。而CPU则使用CS,DS,ES,SS等寄存器来保存程序的段首地址。当CPU执行指令需要访问内存时,只会送出段内的偏移地址,而通过指令的类型类确定访问那一个段寄存器。具体可以参考:计算机原理学习(5)-- x86-16 CPU和内存管理

 

到了IA-32,Intel引入了保护模式,所以在IA-32中为了保持兼容性,所以同样支持内存分段管理。另外我们讨论过了内存分页,页面中包含了程序的代码,数据等信息,它们都有各自的地址。这些地址是在编译的时候就确定的,因为每个进程都有独立完整的内存空间,只需要把页和物理页映射就能运行,所以这个地址是可以在编译时就决定的。在编译时,编译器会等程序进行语法词法等分析,在编译过程中会建立许多的表,来确定代码和变量的虚拟地址:

  • 被保存起来供打印清单的源程序正文;
  • 符号表,包含变量的名字和属性;
  • 包含所有用到的整形和浮点型数据的表;
  • 语法分析树,包括程序语法分析的结果;
  • 编译器内部过程调用的堆栈。

前面4张表会随着编译的进行不断增大,而堆栈的数据也会变化,现在的问题就是,每一张表的大小都不确定,那么如何指定每一张表在虚拟内存空间的地址呢?

如上图,没一张表都有自己的起始地址,但是当变量很多的时候,符号表需要的空间可能会超过程序正文的起始地址,这个时候就会把源程序的表的地址覆盖掉。当然编译器没有这么傻,它可以提示无法继续编译,当然这样并不合适,另一个办法就是拿出一部分没有使用的空间给符号表。造成这个问题的原因就是分页系统中的虚拟地址是一维的,所以在编译过程中必须给变量,代码分配虚拟地址。这个有点类似没有采用分页之前,进程之间使用物理地址导致相互覆盖的问题。

所以我们可以为不同的表分配自己的空间地址,也就是分段,这样他们地址都是相对地址,全部编译完成后确定了每张表的大小,就可以计算出实际的虚拟地址了。

 

 

 

1.2 分段的作用

 

 

分页实际是一个纯粹逻辑上的概念,因为实际的程序和内存并没有被真正的分为了不同的页面。而分段则不同,他是一个逻辑实体。一个段中可以是变量,源代码或者堆栈。一般来说每个段中不会包含不同类型的内容。而分段主要有以下几个作用:

  1. 解决编译问题: 前面提到过在编译时地址覆盖的问题,可以通过分段来解决,从而简化编译程序。
  2. 重新编译: 因为不同类型的数据在不同的段中,但其中一个段进行修改后,就不需要所有的段都重新进行编译。
  3. 内存共享: 对内存分段,可以很容易把其中的代码段或数据段共享给其他程序,分页中因为数据代码混合在一个页面中,所以不便于共享。
  4. 安全性: 将内存分为不同的段之后,因为不同段的内容类型不同,所以他们能进行的操作也不同,比如代码段的内容被加载后就不应该允许写的操作,因为这样会改变程序的行为。而在分页系统中,因为一个页不是一个逻辑实体,代码和数据可能混合在一起,无法进行安全上的控制。
  5. 动态链接: 动态链接是指在作业运行之前,并不把几个目标程序段链接起来。要运行时,先将主程序所对应的目标程序装入内存并启动运行,当运行过程中又需要调用某段时,才将该段(目标程序)调入内存并进行链接。可见,动态链接也要求以段作为管理的单位。
  6. 保持兼容性

所以在现在的x86的体系结构中分段内存管理是必选的,而分页管理则是可选的。

 

 

 

1.3 与x86-16分段管理的区别

 

 

Intel对分段内存管理逻辑地址的定义是【段号+段内地址】。在x86-16体系的分段管理中,CPU给出的内存地址是16位的段内偏移地址,段的基址从段寄存器中获得,最后计算出24位的物理地址。 而在IA-32体系中引入了保护模式,每个进程有4G的独立地址空间,CPU直接给出的是32位的段内偏移地址,段的基址从内存中获得,最后计算出32为的物理地址。他们最大的不同就在于获取基址的方式以及计算方法。

 

 

IA-32为了保持向前兼容,保留了CS/DS/ES/SS这4个寄存器,但因为不在从段寄存器中获得段价值,这4个段寄存器实际上已经失去了原本的作用(但不代表没有使用)。IA-32在内存中使用一张段表来记录各个段映射的物理内存地址(如下图)。

在译地的过程中,x86-16是通过16位的段基址和16位的段内偏移不是简单的相加,而是通过 段值*0x10 + 偏移地址 对基址重定向的方式计算得到物理地址,而IA-32中则相对简单,不需要对基址重定向,这一点和前面分页内存管理是相似的。而CPU只需要为这个段表提供一个记录其首地址的寄存器就可以了。 同样也可以使用TLB来加速。

与x86-16中分段管理另一个不同是,在IA-32中,因为有了独立的地址空间,对多程序也支持的非常好。而分段可以很好的支持进程间数据的共享。

 

 

 

 

2. 分段内存管理

 

 

2.1 段选择器

 

在IA-32中保留的CS/DS/ES/SS这4个16位段寄存器不再被解释为段的基地址,Intel为了保持兼容性将这些寄存器的16个位分成3个用于不同功能的域,称为段选择器

其中3-15是选择子,存放的是段描述符的索引(可以理解为段号),该描述符为64bit用于描述存储器段的位置、长度和访问权限。而段描述符可以分为两种,全局描述符(GDT)局部描述符(LDT),对应着第2位,而0,1两位是表示CPU的权限级别(0-4级)。在IA-32中一共有6个段选择器

 

  • CS保存了代码段描述符的索引;
  • DS保存了数据段描述符的索引;
  • SS保存堆栈段描述符索引;
  • ES、FS、GS则作为一般用途,可以指向任意的数据段,实现自定义寻址。

 

 

2.2 段描述符

 

段描述符就是前面说到的段表中的每一个项目的,一个段描述符由8个字节组成。它描述了段的特征。前面提到段描述符可以分为GDT和LDT两类。通常来说系统只定义一个GDT,而每个进程如果需要放置一些自定义的段,就可以放在自己的LDT中。IA-32中引入了GDTR和LDTR两个寄存器,就是用来存放当前正在使用的GDT和LDT的首地址。

 

上面的图是Linux中不同段的描述符,结构基本是一致的,只有少数字段有差别。其中最重要的就是BASE字段,一共32位,保存的是当前段的首地址。 在Linux系统中,每个CPU对应一个GDT。一个GDT中有18个段描述符和14个未使用或保留项。其中用户和内核各有一个代码段和数据段,然后还包含一个TSS任务段来保存寄存器的状态。其他的段则包括局部线程存储,电源管理,即插即用等多个段。而Linux系统中,大多数用户态的程序都不使用LDT。

 

 

 

2.3 段地址转换

 

 

在IA-32中,逻辑地址是16位的段选择符+32位偏移地址,段寄存器不在保存段基址,而是保存段描述符的索引。

 

 

  1. IA-32首选确定要访问的段(方式x86-16相同),然后决定使用的段寄存器。
  2. 根据段选择符号的TI字段决定是访问GDT还是LDT,他们的首地址则通过GTDR和LDTR来获得。
  3. 将段选择符的Index字段的值*8,然后加上GDT或LDT的首地址,就能得到当前段描述符的地址。(乘以8是因为段描述符为8字节)
  4. 得到段描述符的地址后,可以通过段描述符中BASE获得段的首地址。
  5. 将逻辑地址中32位的偏移地址和段首地址相加就可以得到实际要访问的物理地址。

 

 

2.4 缓存段描述符

 

为了加速地址转换的过程,根据程序的局部性原理,我们可以讲当前段寄存器指向的段描述符缓存在特定的寄存器中。这里为6个段寄存器准备了6个用来缓存段描述符的非编程寄存器。这样就能加快地址转换的过程。而仅当段寄存器内容变化时,才有必要去访问内存中的GDT或LDT。

 

 

 

3. 段页式内存管理

 

 

分段内存管理的优势在于内存共享和安全控制,而分页内存管理的优势在于提高内利用率。他们之间并不是相互对立的竞争关系,而是可以相互补充的。也就是可以把2种方式结合起来,也就是目前计算机中最普遍采用的段页式内存管理。段页式管理的核心就是对内存进行分段,对每个段进行分页。这样在拥有了分段的优势的同时,可以更加合理的使用内存的物理页。

 

 

2.1  段页式内存管理结构

 

对于段页式管理来说,我们需要通过段表来保存每一个段的信息,通过页表保存每个段中虚拟页的信息。在段页管理的系统中,CPU给出的不再是分页系统中的虚拟地址,而是给出的逻辑地址。(前面2篇有介绍逻辑地址和虚拟地址,简单的说逻辑地址是二维的,而虚拟地址是一维的,平坦的)。

 

 

 

2.2 段页式地址转换

 

 

 

上面的图简单的描述了在段页式内存管理的系统中,地址转换的过程。实际上就是我们前面介绍的分段和分页地址转换的结合。

  1. CPU给出要访问的逻辑地址;
  2. 通过分段内存管理的地址转换机制,将逻辑地址转换为线性地址,也就是分页系统中的虚拟地址;
  3. 通过分页内存管理的地址转换机制,将虚拟地址转换为物理地址;

 

 

 

 4. 总结

 

 

这一篇文章主要介绍了IA-32系统中分段式内存管理是如何工作的。而目前主流的系统中都采用了段页相结合的内存管理方式,当然不同的系统具体实现起来是不同的。比如在Linux中,所有段首地址都是从0x0000000开始,所以逻辑地址和转换得到的线性地址完全是一样的。到这一篇,有关x86的内存管理方式以及介绍晚了。内存的分页和分段也决定了程序的编译,可执行文件的结构,程序的内存布局等等。这个将在后面介绍到。

 

 

 

参考

 

《深入理解Linux内核第三版》

 

《现代操作系统》

 

  • 10
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
目录 第一篇 x86 基础 第1 章数与数据类型2 1.1 数 2 1.1.1 数字 2 1.1.2 二进制数 3 1.1.3 二进制数的排列 3 1.1.4 十六进制数 5 1.1.5 八进制数与十进制数 5 1.2 数据类型 6 1.2.1 integer 数 6 1.2.2 floating-point 数. 9 1.2.3 real number(实数)与NaN(not a number) . 11 1.2.4 unsupported 编码值 14 1.2.5 浮点数精度的转换 15 1.2.6 浮点数的溢出 17 1.2.7 BCD 码 20 1.2.8 SIMD 数据 21 第2 章 x86/x64 编程基础 23 2.1 选择编译器 23 2.2 机器语言 24 2.3 Hello world 25 2.3.1 使用寄存器传递参数 26 2.3.2 调用过程 27 2.3.3 定义变量 27 2.4 16 位编程、32 位编程,以及64 位编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 位模下的内存地址 30 2.4.4 内存寻址模 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 34 2.5 编程基础 34 2.5.1 操作数寻址 35 2.5.2 传送数据指令 39 2.5.3 位操作指令 45 2.5.4 算术指令 47 2.5.5 CALL 与RET 指令 48 2.5.6 跳转指令 48 2.6 编辑与编译、运行 48 第 3 章编写本书的实验例子 50 3.1 实验的运行环境 50 3.2 生成空白的映像文件 52 3.2.1 使用nasm 编译器生成 52 3.2.2 使用bximage 工具 52 3.3 设置bochs 配置文件. 53 3.4 源代码的基本结构 54 3.5 编译源代码55 3.6 映像文件内的组织 55 3.7 使用merge 工具 56 3.7.1 merge 的配置文件 57 3.7.2 执行merge 命令 57 3.8 使用U 盘启动真实机器 58 3.8.1 使用merge 工具写U 盘 58 3.8.2 使用hex 编辑软件写U 盘 59 3.9 编写boot 代码 60 3.9.1 LBA 转换为CHS 62 3.9.2 测试是否支持int 13h 扩展功能 63 3.9.3 使用int 13h 扩展读磁盘 64 3.9.4 最后看看load_module() 64 3.10 总结 66 第4 章处理器的身份 67 4.1 测试是否支持CPUID 指令 67 4.2 CPUID 指令的术语及表达 68 4.3 基本信息与扩展信息 68 4.4 处理器的型号(family,model 与stepping) 72 4.5 最大的物理地址和线性地址 73 4.6 处理器扩展状态信息74 4.6.1 探测Processor Extended State 子叶 75 4.6.2 Processor Extended State 子叶所需内存size 76 4.6.3 Processor Extended State 的保存 77 4.6.4 Processor Extended State 的恢复 78 4.7 处理器的特性 78 4.8 处理器的Cache 与TLB 信息 80 4.9 MONITOR/MWAIT 信息 83 4.10 处理器的long mode 84 第 5 章了解 Flags 85 5.1 Eflags 中的状态标志位 86 5.1.1 signed 数的运算 86 5.1.2 unsigned 数的运算 89 5.2 IOPL 标志位 90 5.3 TF 标志与RF 标志 93 5.4 NT 标志 95 5.5 AC 标志 96 5.6 VM 标志 98 5.7 eflags 寄存器的其他事项 99 第 6 章处理器的控制寄存器 101 6.1 CR8 102 6.2 CR3 103 6.3 CR0 104 6.3.1 保护模位PE 104 6.3.2 x87 FPU 单元的执行环境 104 6.3.3 CR0.PG 控制位 108 6.3.4 CR0.CD 与CR0.NW 控制位 108 6.3.5 CR0.WP 控制位 110 6.3.6 CR0.AM 控制位 110 6.4 CR4 110 6.4.1 CR4.TSD 与CR4.PCE 控制位 110 6.4.2 CR4.DE 与CR4.MCD 控制位 111 6.4.3 CR4.OSFXSR 控制位 111 6.4.4 CR4.VMXE 与CR4.SMXE 控制位 111 6.4.5 CR4.PCIDE 与CR4.SMEP 控制位 112 6.4.6 CR4.OSXSAVE 控制位 113 6.4.7 CR4 中关于页的控制位 113 6.5 EFER 扩展功能寄存器 114 第 7 章 MSR. 116 7.1 MSR 的使用 116 7.2 MTRR 117 7.2.1 Fixed-range 区域的映射 118 7.2.2 MTRR 的功能寄存器 120 7.3 MSR 中对特殊指令的支持 124 7.3.1 支持sysenter/sysexit 指令的MSR 125 7.3.2 支持syscall/sysret 指令的MSR 126 7.3.3 支持swapgs 指令的MSR 127 7.3.4 支持monitor/mwait 指令的MSR 128 7.4 提供processor feature 管理 129 7.5 其他未列出来的MSR 129 7.6 关于MSR 一些后续说明 129 第二篇 处理器的工作模 第8 章实地址模 132 8.1 真实的地址 132 8.2 real mode 的编址 132 8.3 real mode 的状态 133 8.4 基址的计算 134 8.5 第1 条执行的指令 134 8.6 实模下的执行环境 135 8.7 实模下的IVT 135 8.8 突破64K 限 136 8.9 A20 地址线 137 第 9 章 SMM系统管理探索 138 9.1 进入SMM 138 9.2 SMM 的运行环境 141 9.2.1 SMRAM 区域 141 9.2.2 SMM 执行环境的初始化 143 9.2.3 SMM 下的operand 与address 144 9.2.4 SMM 下的CS 与EIP 144 9.2.5 SMM 下的SS 与ESP 145 9.3 SMM 里的中断 145 9.4 SMI 的Back-to-Back 响应 147 9.5 SMM 里开启保护模 147 9.6 SMM 的版本 148 9.7 I/O 指令的重启及Halt 重启 151 9.8 SMM 的退出 152 9.9 SMBASE 的重定位. 153 9.10 SMI 处理程序的初始化 154 9.11 SMM 的安全 156 9.11.1 芯片组的控制 156 9.11.2 处理器对SMRAM 空间的限制 158 9.11.3 cache 的限制 160 9.12 测试SMI 处理程序 161 第 10 章 x86/x64 保护模体系(上) 163 10.1 x86/x64 的权限 164 10.2 保护模下的环境 164 10.2.1 管理所使用的资源 165 10.2.2 paging 分页机制所使用的资源 165 10.3 物理地址的产生 166 10.4 管理机制 167 10.4.1 内存管理 168 10.4.2 的保护措施 168 10.5 管理的数据结构 169 10.5.1 Segment Selector(选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(寄存器) 174 10.5.4 Segment Descriptor(描述符) 175 10.5.5 LDT 描述符与LDT 258 10.6 开启保护模 259 10.6.1 初始化GDT 260 10.6.2 初始化IDT. 262 10.6.3 切换到保护模 263 第11 章 x86/x64 保护模体系(下) 265 11.1 物理页面 265 11.1.1 处理器的最高物理地址(MAXPHYADDR) 266 11.1.2 物理页面的大小 267 11.1.3 页转换模(Paging Mode) 268 11.2 paging 机制下使用的资源 270 11.2.1 寄存器 270 11.2.2 CPUID 查询leaf 270 11.2.3 寄存器的控制位 271 11.2.4 页转换表资源 272 11.3 32 位paging 模(non-PAE 模) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模. 282 11.4.1 在Intel64 下的CR3 与PDPTE 寄存器 283 11.4.2 在AMD64 下的CR3 285 11.4.3 PAE paging 模里的PDPTE 结构 286 11.4.4 PAE paging 模里的PDE 结构 286 11.4.5 PAE paging 模里的PTE 结构 288 11.4.6 使用和测试PAE paging 模 288 11.4.7 使用和测试Execution Disable 功能 292 11.5 IA-32e pagi
目录 第一篇 x86 基础 第1 章数与数据类型2 1.1 数 2 1.1.1 数字 2 1.1.2 二进制数 3 1.1.3 二进制数的排列 3 1.1.4 十六进制数 5 1.1.5 八进制数与十进制数 5 1.2 数据类型 6 1.2.1 integer 数 6 1.2.2 floating-point 数. 9 1.2.3 real number(实数)与NaN(not a number) . 11 1.2.4 unsupported 编码值 14 1.2.5 浮点数精度的转换 15 1.2.6 浮点数的溢出 17 1.2.7 BCD 码 20 1.2.8 SIMD 数据 21 第2 章 x86/x64 编程基础 23 2.1 选择编译器 23 2.2 机器语言 24 2.3 Hello world 25 2.3.1 使用寄存器传递参数 26 2.3.2 调用过程 27 2.3.3 定义变量 27 2.4 16 位编程、32 位编程,以及64 位编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 位模下的内存地址 30 2.4.4 内存寻址模 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 34 2.5 编程基础 34 2.5.1 操作数寻址 35 2.5.2 传送数据指令 39 2.5.3 位操作指令 45 2.5.4 算术指令 47 2.5.5 CALL 与RET 指令 48 2.5.6 跳转指令 48 2.6 编辑与编译、运行 48 第 3 章编写本书的实验例子 50 3.1 实验的运行环境 50 3.2 生成空白的映像文件 52 3.2.1 使用nasm 编译器生成 52 3.2.2 使用bximage 工具 52 3.3 设置bochs 配置文件. 53 3.4 源代码的基本结构 54 3.5 编译源代码55 3.6 映像文件内的组织 55 3.7 使用merge 工具 56 3.7.1 merge 的配置文件 57 3.7.2 执行merge 命令 57 3.8 使用U 盘启动真实机器 58 3.8.1 使用merge 工具写U 盘 58 3.8.2 使用hex 编辑软件写U 盘 59 3.9 编写boot 代码 60 3.9.1 LBA 转换为CHS 62 3.9.2 测试是否支持int 13h 扩展功能 63 3.9.3 使用int 13h 扩展读磁盘 64 3.9.4 最后看看load_module() 64 3.10 总结 66 第4 章处理器的身份 67 4.1 测试是否支持CPUID 指令 67 4.2 CPUID 指令的术语及表达 68 4.3 基本信息与扩展信息 68 4.4 处理器的型号(family,model 与stepping) 72 4.5 最大的物理地址和线性地址 73 4.6 处理器扩展状态信息74 4.6.1 探测Processor Extended State 子叶 75 4.6.2 Processor Extended State 子叶所需内存size 76 4.6.3 Processor Extended State 的保存 77 4.6.4 Processor Extended State 的恢复 78 4.7 处理器的特性 78 4.8 处理器的Cache 与TLB 信息 80 4.9 MONITOR/MWAIT 信息 83 4.10 处理器的long mode 84 第 5 章了解 Flags 85 5.1 Eflags 中的状态标志位 86 5.1.1 signed 数的运算 86 5.1.2 unsigned 数的运算 89 5.2 IOPL 标志位 90 5.3 TF 标志与RF 标志 93 5.4 NT 标志 95 5.5 AC 标志 96 5.6 VM 标志 98 5.7 eflags 寄存器的其他事项 99 第 6 章处理器的控制寄存器 101 6.1 CR8 102 6.2 CR3 103 6.3 CR0 104 6.3.1 保护模位PE 104 6.3.2 x87 FPU 单元的执行环境 104 6.3.3 CR0.PG 控制位 108 6.3.4 CR0.CD 与CR0.NW 控制位 108 6.3.5 CR0.WP 控制位 110 6.3.6 CR0.AM 控制位 110 6.4 CR4 110 6.4.1 CR4.TSD 与CR4.PCE 控制位 110 6.4.2 CR4.DE 与CR4.MCD 控制位 111 6.4.3 CR4.OSFXSR 控制位 111 6.4.4 CR4.VMXE 与CR4.SMXE 控制位 111 6.4.5 CR4.PCIDE 与CR4.SMEP 控制位 112 6.4.6 CR4.OSXSAVE 控制位 113 6.4.7 CR4 中关于页的控制位 113 6.5 EFER 扩展功能寄存器 114 第 7 章 MSR. 116 7.1 MSR 的使用 116 7.2 MTRR 117 7.2.1 Fixed-range 区域的映射 118 7.2.2 MTRR 的功能寄存器 120 7.3 MSR 中对特殊指令的支持 124 7.3.1 支持sysenter/sysexit 指令的MSR 125 7.3.2 支持syscall/sysret 指令的MSR 126 7.3.3 支持swapgs 指令的MSR 127 7.3.4 支持monitor/mwait 指令的MSR 128 7.4 提供processor feature 管理 129 7.5 其他未列出来的MSR 129 7.6 关于MSR 一些后续说明 129 第二篇 处理器的工作模 第8 章实地址模 132 8.1 真实的地址 132 8.2 real mode 的编址 132 8.3 real mode 的状态 133 8.4 基址的计算 134 8.5 第1 条执行的指令 134 8.6 实模下的执行环境 135 8.7 实模下的IVT 135 8.8 突破64K 限 136 8.9 A20 地址线 137 第 9 章 SMM系统管理探索 138 9.1 进入SMM 138 9.2 SMM 的运行环境 141 9.2.1 SMRAM 区域 141 9.2.2 SMM 执行环境的初始化 143 9.2.3 SMM 下的operand 与address 144 9.2.4 SMM 下的CS 与EIP 144 9.2.5 SMM 下的SS 与ESP 145 9.3 SMM 里的中断 145 9.4 SMI 的Back-to-Back 响应 147 9.5 SMM 里开启保护模 147 9.6 SMM 的版本 148 9.7 I/O 指令的重启及Halt 重启 151 9.8 SMM 的退出 152 9.9 SMBASE 的重定位. 153 9.10 SMI 处理程序的初始化 154 9.11 SMM 的安全 156 9.11.1 芯片组的控制 156 9.11.2 处理器对SMRAM 空间的限制 158 9.11.3 cache 的限制 160 9.12 测试SMI 处理程序 161 第 10 章 x86/x64 保护模体系(上) 163 10.1 x86/x64 的权限 164 10.2 保护模下的环境 164 10.2.1 管理所使用的资源 165 10.2.2 paging 分页机制所使用的资源 165 10.3 物理地址的产生 166 10.4 管理机制 167 10.4.1 内存管理 168 10.4.2 的保护措施 168 10.5 管理的数据结构 169 10.5.1 Segment Selector(选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(寄存器) 174 10.5.4 Segment Descriptor(描述符) 175 10.5.5 LDT 描述符与LDT 258 10.6 开启保护模 259 10.6.1 初始化GDT 260 10.6.2 初始化IDT. 262 10.6.3 切换到保护模 263 第11 章 x86/x64 保护模体系(下) 265 11.1 物理页面 265 11.1.1 处理器的最高物理地址(MAXPHYADDR) 266 11.1.2 物理页面的大小 267 11.1.3 页转换模(Paging Mode) 268 11.2 paging 机制下使用的资源 270 11.2.1 寄存器 270 11.2.2 CPUID 查询leaf 270 11.2.3 寄存器的控制位 271 11.2.4 页转换表资源 272 11.3 32 位paging 模(non-PAE 模) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模. 282 11.4.1 在Intel64 下的CR3 与PDPTE 寄存器 283 11.4.2 在AMD64 下的CR3 285 11.4.3 PAE paging 模里的PDPTE 结构 286 11.4.4 PAE paging 模里的PDE 结构 286 11.4.5 PAE paging 模里的PTE 结构 288 11.4.6 使用和测试PAE paging 模 288 11.4.7 使用和测试Execution Disable 功能 292 11.5 IA-32e pagi
目录 第一篇 x86 基础 第1 章数与数据类型2 1.1 数 2 1.1.1 数字 2 1.1.2 二进制数 3 1.1.3 二进制数的排列 3 1.1.4 十六进制数 5 1.1.5 八进制数与十进制数 5 1.2 数据类型 6 1.2.1 integer 数 6 1.2.2 floating-point 数. 9 1.2.3 real number(实数)与NaN(not a number) . 11 1.2.4 unsupported 编码值 14 1.2.5 浮点数精度的转换 15 1.2.6 浮点数的溢出 17 1.2.7 BCD 码 20 1.2.8 SIMD 数据 21 第2 章 x86/x64 编程基础 23 2.1 选择编译器 23 2.2 机器语言 24 2.3 Hello world 25 2.3.1 使用寄存器传递参数 26 2.3.2 调用过程 27 2.3.3 定义变量 27 2.4 16 位编程、32 位编程,以及64 位编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 位模下的内存地址 30 2.4.4 内存寻址模 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 34 2.5 编程基础 34 2.5.1 操作数寻址 35 2.5.2 传送数据指令 39 2.5.3 位操作指令 45 2.5.4 算术指令 47 2.5.5 CALL 与RET 指令 48 2.5.6 跳转指令 48 2.6 编辑与编译、运行 48 第 3 章编写本书的实验例子 50 3.1 实验的运行环境 50 3.2 生成空白的映像文件 52 3.2.1 使用nasm 编译器生成 52 3.2.2 使用bximage 工具 52 3.3 设置bochs 配置文件. 53 3.4 源代码的基本结构 54 3.5 编译源代码55 3.6 映像文件内的组织 55 3.7 使用merge 工具 56 3.7.1 merge 的配置文件 57 3.7.2 执行merge 命令 57 3.8 使用U 盘启动真实机器 58 3.8.1 使用merge 工具写U 盘 58 3.8.2 使用hex 编辑软件写U 盘 59 3.9 编写boot 代码 60 3.9.1 LBA 转换为CHS 62 3.9.2 测试是否支持int 13h 扩展功能 63 3.9.3 使用int 13h 扩展读磁盘 64 3.9.4 最后看看load_module() 64 3.10 总结 66 第4 章处理器的身份 67 4.1 测试是否支持CPUID 指令 67 4.2 CPUID 指令的术语及表达 68 4.3 基本信息与扩展信息 68 4.4 处理器的型号(family,model 与stepping) 72 4.5 最大的物理地址和线性地址 73 4.6 处理器扩展状态信息74 4.6.1 探测Processor Extended State 子叶 75 4.6.2 Processor Extended State 子叶所需内存size 76 4.6.3 Processor Extended State 的保存 77 4.6.4 Processor Extended State 的恢复 78 4.7 处理器的特性 78 4.8 处理器的Cache 与TLB 信息 80 4.9 MONITOR/MWAIT 信息 83 4.10 处理器的long mode 84 第 5 章了解 Flags 85 5.1 Eflags 中的状态标志位 86 5.1.1 signed 数的运算 86 5.1.2 unsigned 数的运算 89 5.2 IOPL 标志位 90 5.3 TF 标志与RF 标志 93 5.4 NT 标志 95 5.5 AC 标志 96 5.6 VM 标志 98 5.7 eflags 寄存器的其他事项 99 第 6 章处理器的控制寄存器 101 6.1 CR8 102 6.2 CR3 103 6.3 CR0 104 6.3.1 保护模位PE 104 6.3.2 x87 FPU 单元的执行环境 104 6.3.3 CR0.PG 控制位 108 6.3.4 CR0.CD 与CR0.NW 控制位 108 6.3.5 CR0.WP 控制位 110 6.3.6 CR0.AM 控制位 110 6.4 CR4 110 6.4.1 CR4.TSD 与CR4.PCE 控制位 110 6.4.2 CR4.DE 与CR4.MCD 控制位 111 6.4.3 CR4.OSFXSR 控制位 111 6.4.4 CR4.VMXE 与CR4.SMXE 控制位 111 6.4.5 CR4.PCIDE 与CR4.SMEP 控制位 112 6.4.6 CR4.OSXSAVE 控制位 113 6.4.7 CR4 中关于页的控制位 113 6.5 EFER 扩展功能寄存器 114 第 7 章 MSR. 116 7.1 MSR 的使用 116 7.2 MTRR 117 7.2.1 Fixed-range 区域的映射 118 7.2.2 MTRR 的功能寄存器 120 7.3 MSR 中对特殊指令的支持 124 7.3.1 支持sysenter/sysexit 指令的MSR 125 7.3.2 支持syscall/sysret 指令的MSR 126 7.3.3 支持swapgs 指令的MSR 127 7.3.4 支持monitor/mwait 指令的MSR 128 7.4 提供processor feature 管理 129 7.5 其他未列出来的MSR 129 7.6 关于MSR 一些后续说明 129 第二篇 处理器的工作模 第8 章实地址模 132 8.1 真实的地址 132 8.2 real mode 的编址 132 8.3 real mode 的状态 133 8.4 基址的计算 134 8.5 第1 条执行的指令 134 8.6 实模下的执行环境 135 8.7 实模下的IVT 135 8.8 突破64K 限 136 8.9 A20 地址线 137 第 9 章 SMM系统管理探索 138 9.1 进入SMM 138 9.2 SMM 的运行环境 141 9.2.1 SMRAM 区域 141 9.2.2 SMM 执行环境的初始化 143 9.2.3 SMM 下的operand 与address 144 9.2.4 SMM 下的CS 与EIP 144 9.2.5 SMM 下的SS 与ESP 145 9.3 SMM 里的中断 145 9.4 SMI 的Back-to-Back 响应 147 9.5 SMM 里开启保护模 147 9.6 SMM 的版本 148 9.7 I/O 指令的重启及Halt 重启 151 9.8 SMM 的退出 152 9.9 SMBASE 的重定位. 153 9.10 SMI 处理程序的初始化 154 9.11 SMM 的安全 156 9.11.1 芯片组的控制 156 9.11.2 处理器对SMRAM 空间的限制 158 9.11.3 cache 的限制 160 9.12 测试SMI 处理程序 161 第 10 章 x86/x64 保护模体系(上) 163 10.1 x86/x64 的权限 164 10.2 保护模下的环境 164 10.2.1 管理所使用的资源 165 10.2.2 paging 分页机制所使用的资源 165 10.3 物理地址的产生 166 10.4 管理机制 167 10.4.1 内存管理 168 10.4.2 的保护措施 168 10.5 管理的数据结构 169 10.5.1 Segment Selector(选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(寄存器) 174 10.5.4 Segment Descriptor(描述符) 175 10.5.5 LDT 描述符与LDT 258 10.6 开启保护模 259 10.6.1 初始化GDT 260 10.6.2 初始化IDT. 262 10.6.3 切换到保护模 263 第11 章 x86/x64 保护模体系(下) 265 11.1 物理页面 265 11.1.1 处理器的最高物理地址(MAXPHYADDR) 266 11.1.2 物理页面的大小 267 11.1.3 页转换模(Paging Mode) 268 11.2 paging 机制下使用的资源 270 11.2.1 寄存器 270 11.2.2 CPUID 查询leaf 270 11.2.3 寄存器的控制位 271 11.2.4 页转换表资源 272 11.3 32 位paging 模(non-PAE 模) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模. 282 11.4.1 在Intel64 下的CR3 与PDPTE 寄存器 283 11.4.2 在AMD64 下的CR3 285 11.4.3 PAE paging 模里的PDPTE 结构 286 11.4.4 PAE paging 模里的PDE 结构 286 11.4.5 PAE paging 模里的PTE 结构 288 11.4.6 使用和测试PAE paging 模 288 11.4.7 使用和测试Execution Disable 功能 292 11.5 IA-32e pagi

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值