首页 物联网

《操作系统真象还原》第九章:保护模式下内存寻址与分段机制深度解析

分类:物联网
字数: (6289)
阅读: (6738)
内容摘要:《操作系统真象还原》第九章:保护模式下内存寻址与分段机制深度解析,

《操作系统真象还原》第九章的第二部分,主要探讨了保护模式下的内存寻址和分段机制。这对于理解操作系统的内存管理至关重要。在实模式下,寻址方式简单直接,但也带来了诸多限制。而保护模式引入了分段机制,极大地提升了内存管理的灵活性和安全性。本文将结合实际案例,深入剖析这一机制,并分享一些实战中的避坑经验。

分段机制的核心概念

分段机制将线性地址空间划分为多个段,每个段由段选择子(Segment Selector)和段描述符(Segment Descriptor)定义。段选择子用于选择对应的段描述符,而段描述符则包含了段的基地址、段界限、段属性等关键信息。通过这种方式,可以将程序的不同部分(代码、数据、堆栈等)放置在不同的段中,并赋予不同的访问权限,从而实现内存的隔离和保护。这类似于我们在使用 Nginx 进行反向代理时,会根据不同的 URL 将请求转发到不同的后端服务器,实现请求的隔离和路由。

《操作系统真象还原》第九章:保护模式下内存寻址与分段机制深度解析

段选择子(Segment Selector)详解

段选择子是一个 16 位的值,它并不直接指向内存地址,而是作为一个索引,指向全局描述符表(GDT)或局部描述符表(LDT)中的段描述符。其结构通常包括:

《操作系统真象还原》第九章:保护模式下内存寻址与分段机制深度解析
  • 请求特权级(RPL):指示请求者的特权级别。
  • 表指示器(TI):指示使用 GDT 还是 LDT。
  • 索引(Index):GDT 或 LDT 中的条目索引,指向具体的段描述符。
// 示例:段选择子的结构
typedef struct {
  unsigned int RPL : 2;  // 请求特权级
  unsigned int TI : 1;   // 表指示器 (0: GDT, 1: LDT)
  unsigned int Index : 13; // 索引
} SegmentSelector;

段描述符(Segment Descriptor)详解

段描述符是一个 8 字节(64位)的数据结构,包含了段的全部信息,包括:

《操作系统真象还原》第九章:保护模式下内存寻址与分段机制深度解析
  • 段基地址(Base Address):段的起始地址。
  • 段界限(Segment Limit):段的大小。
  • 段属性(Attributes):包括段的类型、访问权限、可读/写/执行等属性。
// 示例:段描述符的结构
typedef struct {
  unsigned short LimitLow;       // 段界限 (0-15 位)
  unsigned short BaseLow;        // 段基地址 (0-15 位)
  unsigned char BaseMid;         // 段基地址 (16-23 位)
  unsigned char Attributes1;     // 属性 1
  unsigned char LimitHigh_Attr2; // 段界限 (16-19 位) + 属性 2
  unsigned char BaseHigh;        // 段基地址 (24-31 位)
} SegmentDescriptor;

实战:配置 GDT 实现内存分段

配置 GDT 是实现内存分段的关键步骤。我们需要创建 GDT 表,并在其中添加合适的段描述符。例如,我们可以创建一个代码段和一个数据段,分别用于存储代码和数据。设置正确的段属性至关重要,例如代码段需要设置为可执行,数据段需要设置为可读写。

《操作系统真象还原》第九章:保护模式下内存寻址与分段机制深度解析
; 示例:GDT 表的定义
gdt_start:
  dd 0  ; 空描述符 (必须有)

code_segment:
  dw 0FFFFh  ; 段界限 (0-15)
  dw 0        ; 段基地址 (0-15)
  db 0        ; 段基地址 (16-23)
  db 9Ah      ; 属性 (代码段, 可读, 已访问)
  db 0CFh     ; 属性 (粒度, 32位, 段界限 16-19)
  db 0        ; 段基地址 (24-31)

data_segment:
  dw 0FFFFh  ; 段界限 (0-15)
  dw 0        ; 段基地址 (0-15)
  db 0        ; 段基地址 (16-23)
  db 92h      ; 属性 (数据段, 可读写, 已访问)
  db 0CFh     ; 属性 (粒度, 32位, 段界限 16-19)
  db 0        ; 段基地址 (24-31)

gdt_end:

gdt_descriptor:
  dw gdt_end - gdt_start - 1  ; GDT 大小
  dd gdt_start                 ; GDT 起始地址

避坑经验:段属性的正确设置

在配置段描述符时,段属性的设置至关重要。错误的段属性可能导致程序崩溃或安全漏洞。例如,如果将代码段设置为可写,那么程序可能会被恶意修改。因此,务必仔细阅读 Intel 手册,了解各种段属性的含义,并根据实际需求进行配置。此外,在使用 GDT 时,要特别注意 GDT 的大小和地址,确保 GDT 的访问不会越界。这就像在使用宝塔面板配置 Nginx 时,要仔细检查配置文件的语法和参数,避免出现配置错误导致服务不可用。

总结:分段机制的价值

《操作系统真象还原》第九章的第二部分详细讲解了保护模式下的分段机制。理解并掌握分段机制,对于深入理解操作系统的内存管理,以及编写高效、安全的程序至关重要。通过合理地使用分段机制,我们可以实现内存的隔离和保护,提高系统的稳定性和安全性。这就像我们在设计高并发系统时,会采用各种优化策略,例如连接池、缓存、负载均衡等,以提高系统的性能和可用性。

《操作系统真象还原》第九章:保护模式下内存寻址与分段机制深度解析

转载请注明出处: 青衫落拓

本文的链接地址: http://m.acea3.store/blog/952881.SHTML

本文最后 发布于2026-04-15 17:56:34,已经过了12天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 北京炸酱面 2 天前
    不错,文章结构清晰,例子也很贴切。希望能多出一些关于操作系统底层原理的文章。
  • 海王本王 2 天前
    GDT的配置那部分很实用,之前照着书敲代码,总是遇到各种问题,看来是段属性没设置对。
  • 真香警告 6 天前
    感谢分享,关于段选择子的结构解析得很到位,解决了我的一个疑惑。