80386地址转换

80386 地址转换分两种情况:实模式下地址转换、保护模式下地址转换

实模式下地址转换

80386 的实模式是为了兼容 8086 而设计的,8086 的寄存器都是 16 位的,因此可寻址范围是 0x0 - 0xFFFF,即:寻址范围是 0 ~ 64KB,然而处理器的BIU(总线接口单元是20位),因此CPU可寻址范围实际是 0x0 - 0xFFFFF,即:寻址范围是 0 ~ 1MB。

那么如何用 16 位的寄存器,得到 20位 的地址?答案是使用段寄存器左移4位 + 通用寄存器组成了20位地址。

假设DS寄存器的值是: 0x1234,偏移地址是: 0x1234,最终实际寻址的物理地址是:0x13574

实模式下内存寻址:段寄存器 << 4 + 偏移地址

保护模式下地址转换

保护模式下地址转换分为两种情况:

  • 保护模式下开启分页

  • 保护模式下不开启分页

保护模式下不开启分页

物理地址 = 线性地址 = 16位的段选择子 + 32位的偏移量

过程如下:

  1. 使用段选择子获取段描述符

    • 从GDT(全局描述符表)或LDT(局部描述符表)中获取段描述符的索引

    • 根据索引找到对应的段描述符

  2. 将段描述符中的段基址和偏移量相加

    • 从段描述符中获取段基址

    • 将段基址与偏移量相加得到线性地址

  3. 物理地址的计算

    • 执行特权级检查和段界限检查,确保线性地址有效

    • 将线性地址作为物理地址直接访问物理内存

保护模式下开启分页

线性地址 = 16位的段选择子 + 32 位的偏移量
物理地址 <= 线性地址

过程如下:

  1. 线性地址中提取页目录索引(Page Directory Index)、页表索引(Page Table Index)和页内偏移(Page Offset)。

  2. 使用页目录索引作为索引访问页目录表(Page Directory Table),从中获取对应的页目录项(Page Directory Entry)。

  3. 从页目录项中提取页表基址(Page Table Base Address)。

  4. 使用页表索引作为索引访问页表(Page Table),从中获取对应的页表项(Page Table Entry)

  5. 从页表项中提取页框基址(Page Frame Base Address)。

  6. 页框基址 + 页内偏移得到物理地址

具体转换过程如下:

  1. 从线性地址中提取页目录索引、页表索引和页内偏移:

    • 线性地址的高10位是页目录索引

    • 线性地址的中间10位是页表索引

    • 线性地址的低12位是页内偏移

  2. 使用页目录索引访问页目录表

    • 从控制寄存器CR3中获取页目录表基址

    • 使用页目录索引乘以4(每个页目录项占用4个字节)得到页目录项的偏移量

    • 页目录表基址 + 页目录项偏移量 => 页目录项的物理地址

    • 从页目录项的物理地址中获取页表基址

  3. 使用页表索引访问页表

    • 使用页表索引乘以4(每个页表项占用4个字节)得到页表项的偏移量

    • 将页表基址(页表基址保存在页目录项中) + 页表偏移量 => 得到页表项的物理地址

    • 从页表项的物理地址中获取页框基址

  4. 物理地址计算:

    • 将页框基址 + 页内偏移量 => 得到物理地址

页表基址保存在页目录项中。

  1. 从控制寄存器CR3中获取页目录表基址

  2. 使用页目录表索引乘以4(每个页目录项占4个字节)得到页目录项的偏移量

  3. 将页目录表基址与页目录项的偏移量相加,得到页目录项的物理地址

  4. 从页目录项的物理地址中获取页表基址