第二章-内存寻址

1.内存寻址

处理器历史
  • Intel 4004 4位的微处理器
  • Intel 8008 8位的微处理器 可以通过两个次寄存器来访问16位的内存地址,共有2^16个地址也就是64K范围内的地址空间
  • Intel 8086 16位的微处理器
    • 引入 段,:ALU的宽度和地址总线宽度不同
      • 16位的内部地址(高12位和段寄存器16位内容相加再结合剩下的4位凑成20位地址)
    • 地址总线20位,1M地址空间
  • Intel 80286 16位的微处理器
    • 地址总线达到了24位,16M个单元的内存空间
    • 引入保护模式,不能直接从段寄存器中获得基地址了
  • Intel 80386 32位的微处理器 开启80x86
    • 地址总线达到了32位,4G个单元的内存空间
80x86寄存器
  • 8个32位通用寄存器 EAX EBX ECX EDX EBP ESP ESI EDI
  • 4个16位的段寄存器 CS DS SS ES
    • 80x86以前 段寄存器存放段的基地址
    • 80x86以后 段寄存器存放段选择符(段描述符在段表中的索引+TL:决定从LDT还是GDT中惦相应的段描述符+RPL:请求者的特权级别,Linux只使用了最高和最低即内核和用户特权级别)
  • 指令指针寄存器和标志寄存器 EIP EFLAGS
  • 4个32位控制寄存器 CR0 CR1 CR2 CR3 用于分页机制 控制允许分页和及目录基址等
物理地址 线性地址 虚拟地址(逻辑地址)
  • 虚拟地址 段:偏移 表示
  • 线性地址 范围为0-4GB的地址空间
  • 地址转换通过MMU内存管理单元
    • 虚拟地址 -> 线性地址 段机制实现
    • 线性地址 -> 物理地址 页机制实现

段机制

段表和段描述符
  • 段描述符
    • 8字节的数表示(基地址 段长 保护属性)
    • 32位的基地址 20位的段界限(长度)
  • 描述符表
    • 保护模式下还有其他三种描述符表(全局描述符表GDT,中断描述符表IDT,局部描述符表LDT),专门设置GDTR,IDTR,LDTR寄存器存放表的基地址和长度加速访问
  • 地址转换和保护(转换成线性地址)
    • 段寄存器装入选择符,地址偏移量装入寄存器
    • 段描述符放入段描述符高速寄存器
    • 段描述符中的基址和偏移量相加得到线性地址
  • Linux中的段机制(有些处理器不支持段机制)
    • 基地址设为0 段长4GB 即偏移量 = 线性地址
    • 因为1.数据段和代码段需要分别创建 2.Linux的内核特权和用户特权划分 所以需要创建四个段 内核:数据|代码段 用户:数据|代码段
    • 系统启动 设置了段寄存器和全局描述符表

页机制

页 页表和页大小
  • 将线性地址划分成若干大小的片称为页
  • 线性地址空间分页 和 物理地址空间分页
  • 80x86 页大小4KB
  • 页表
    • 页表项 4字节 1.物理页面的基地址 2. 页的属性
    • 4GB线性地址空间可以被划分1M个4KB大小的页
    • 两级页表 解决页表项连续存放需要4M空间的问题
    • 两级页表 线性地址结构 页目录 + 页 + 页内偏移
  • 页表项
    • 物理页基地址
  • 地址转换(线性地址转成物理地址)
    • 获取目录项的地址
    • 获取页表的地址
    • 获取页表项的地址
    • 取出物理基地址加上线性地址中的偏移地址形成物理地址
  • 页面高速缓存TLB
    • 通过缓存页表项来减少两次访问内存

Linux中的分页

三级分页
  • 页总目录PDG,页中间目录PMD,页表PT

你可能感兴趣的:(第二章-内存寻址)