内存寻址

内存地址

  • 逻辑地址

    • 段+偏移量
    • 在机器语言指令中使用的地址
  • 线性地址(虚拟地址)

    • 页式内存转换前的地址
  • 物理地址

    • 芯片级的内存单元地址

硬件中的分段

  • 检查段选择符的TI字段,决定段描述符保存在哪一个描述符表中(TI = 0 表示段描述符在GDT中;TI = 1 表示端描述符在LDT中),针对TI不同的取值,在寄存器gdtr或ldtr中得到GDT或LDT的线性基地址。
  • 从段选择符的index字段计算段描述符的地址。index字段的值×8 + 寄存器中的基地址,得到段描述符的地址。
  • 逻辑地址的偏移量与段描述符中的Base字段的值相加,得到线性地址。

Linux中的分段

  • 运行在用户态下的所有Linux进程都使用一对相同的段对指令和数据寻址(用户代码段和用户数据段);运行在内核态的所有Linux进程都使用一对相同的段对指令和数据寻址(内核代码段和内核数据段)

  • 四个主要Linux段的段描述符取值
    四个主要Linux段的段描述符字段的值.

  • Base值总是从0开始,因此,逻辑地址偏移量字段的值和线性地址一致

  • Linux GDT

    • 每个CPU对应一个GDT
    • 每个GDT包含18个段描述符和14个保留项
      • 4个代码段+数据段(内核态+用户态)
      • 任务状态段(每个处理器一个)
      • ……
  • Linux LDT

硬件中的分页

  • 线性地址转换成物理地址
    • 页内部连续的线性地址被映射到连续的物理内存
    • 32位地址分成3部分:Directory(目录,10位),Table(页表,10位),Offset(偏移量,12位)
    • 在80x86中,页表大小4KB(12位偏移量)
  • 页表

    • 线性地址映射到物理地址的数据结构
    • 存放在主存中
  • 80x86处理器的分页

    • cr3寄存器存储当前运行进程的页目录的物理地址
    • 根据线性地址中的Directory字段,查找到目录项,目录项指向对应的列表
    • 根据线性地址中的TABLE字段,查找页表中的表项,表项包含页所在页框的物理地址
    • Offset决定页框内的相对位置
  • 硬件高速缓存

    • 高速缓存单元位于分页单元和主存之间
    • 对于多处理器系统,每个处理器对应一个硬件高速缓存,硬件层面解决不同高速缓存的同步问题
  • TLB

    • 由于页表存储在RAM中,每次进行线性地址转化是都需要访问一次RAM,时间长
    • TLB: 缓存,存储线性地址和物理地址的对应关系

Linux中的分页

  • Linux 分页模式
    • 四层页管理架构(兼容32位,64位)
      • 页全局目录对应页目录
      • 页表对应页表

参考

  1. https://www.cnblogs.com/zengkefu/p/5452792.html