内存寻址(一) —— 基本概念与机制

1.内存地址

在编程中我们(编译器)为各种数据分配的内存均为逻辑地址,逻辑地址通过操作系统转换为物理地址,也就是芯片级物理内存的地址。在使用Intel 80x86微处理器时,应当分清以下三种“地址”:

  • 逻辑地址(logical address)
  • 线性地址(linear address)
  • 物理地址(physical address)

CPU控制单元通过一种称为分段单元(segmentation unit) 的硬件电路把一个逻辑地址转换成线性地址;
接着,第二个称为 分页单元(paging unit) 的硬件电路把一个线性地址转换成物理地址。
逻辑地址转换

2.分段机制

最早内存没有抽象,程序直接读写物理内存。在这种情况下,通常同时运行两个程序是不可能的,因为它们很可能同时访问同一个物理地址导致程序崩溃。
当Intel 8086处理器出现时,内存寻址迎来第一次飞跃,它引入了一个重要的概念——,段式内存使得程序地址不再需要静态重定位,支持了更大的地址。
8086处理器的数据总线是16位的,但其目标是寻址1MB的内存,这意味着需要20位的地址总线。为了解决这个问题,当时引入了分段的方法。
一个逻辑地址由两部分组成:一个段标识符和一个指定段内相对地址的偏移量。段标识符是一个16 位长的字段,称为段选择符(Segment Selector),而偏移量是一个32 位长的字段。
逻辑地址图示

2.1 段寄存器

为了方便找到段选择符,处理器提供6个段寄存器专门用来存放段选择符。它们是cs、ss、ds、es、fs和gs。

  • **cs位代码段寄存器;
  • ss为栈段寄存器;
  • ds为数据段寄存器;**
  • 其他三个段寄存器作一般用途,6个段寄存器均为16位

2.2 段描述符

每个段由一个8字节的段描述符(segment descriptor)来具体描述。段描述符放在全局描述符表(Global Descriptor Table ,GDT)或局部描述符表(Local Descriptor Table, LDT)中。段描述符标被存在一个非编程CPU寄存器中,非编程寄存器对程序员不可见,仅供6个可编程的段寄存器使用。**
段描述符
B31 ~ B24 和 B23 ~ B16分别为基地址的 bit16 ~ bit23 和 bit24 ~ bit31;
L19 ~ L16和L15 ~ L0为段LIMIT的 bit10 ~ bit15 和 bit16 ~ bit19。

4位type域描述了段的类型特征和存取权限,广泛使用如下几种:
1.代码段描述符(描述符代表一个代码段,可以放在GDT或LDT中,S标志位为1)
2.数据段描述符(描述符代表一个数据段,可以放在GDT或LDT中,S标志位为1)
3.任务状态段描述符(代表一个任务状态段(TSS),只能存放在GDT中,S标志位为9或11)
4.局部描述符表描述符(代表一个LDT段,只能存放在GDT中,S标志位为0)

2.3 段选择符

之前提到16位的段选择符存放在段寄存器中,它直接指向段描述符。每当一个段选择符被装入段寄存器,相应的段描述符就被装入非编程寄存器。*此时CPU只需直接引用段描述符所在寄存器即可,不需访问主存中的GDT或LDT。*仅当段寄存器的内容改变时,才有必要访问GDT或LDT。
在这里插入图片描述
段选择符包含以下域:

  • 13位的索引,指定了段描述符在GDT或LDT中的入口。
  • TI标志指明了段描述符是在GDT中(TI = 0)还是在LDT中( TI = 1)
  • 两位RPL(请求特权级)

在这里插入图片描述

2.4 逻辑地址到线性地址的转换

分段单元(segmentationunit)执行以下操作:

  1. 先检查段选择符的TI字段,以决定段描述符保存在哪一个描述符表中。TI字段指明描述符是在GDT中(在这种情况下,分段单元从GDTR寄存器中得到GDT的线性基地址)还是在LDT中(在这种情况下,分段单元从LDTR寄存器中得到LDT的线性基地址)。
  2. 从段选择符的 index 索引字段计算段描述符的地址,index字段的值乘以8(一个段描述符的大小),这个结果与GDTR或LDTR寄存器中的内容相加
  3. 逻辑地址的偏移量与段描述符基地址域(base)相加,就得到了线性地址。

在这里插入图片描述

3.分页机制

分页单元在分段之后运行,把线性地址转换成物理地址

3.1 页、页框、页表

为了效率起见,线性地址被分成以固定长度为单位的组,称为页(page)。页内部连续的线性地址被映射到连续的物理地址中。这样,内核可以指定一个页的物理地址和其存取权限,而不用指定页所包含的全部线性地址的存取权限。

分页单元把所有的RAM 分成固定长度的页框(page frame)。每一个页框包含一个页,也就是说一个页框的长度与一个页的长度一致。页框是主存的一部分,因此也是一个存储区域。
区分一页和一个页框是很重要的,前者只是一个数据块,可以存放在任何页框或磁盘中。

把线性地址映射到物理地址的数据结构称为页表(page table)。页表存放在主存中,并在启用分页单元之前必须由内核对页表进行适当的初始化。

3.2 常规分页

从80386 起,Intel 处理器的分页单元处理4KB 的页。32 位的线性地址被分成 3 个域:

  • Directory(目录):最高10 位
  • Table(页表):中间10 位
  • Offset(偏移量):最低12 位

在这里插入图片描述
Directory域和Table域都是10位,它们拥有相同的结构,均包含以下的域:

  • Present 标志
  • Accessed 标志
  • Dirty 标志
  • Read/Write 标志
  • User/Supervisor 标志
  • PCD 和 PWT 标志
  • Page Size 标志
  • Global 标志

3.3 线性地址转换为物理地址

线性地址的转换分两步完成,每一步都基于一种转换表,第一种转换表称为页目录表,第二种转换表称为页表
正在使用的页目录的物理地址存放在控制寄存器 cr3 中。线性地址内的Directory 字段决定页目录中的目录项,而目录项指向适当的页表。地址的Table 字段依次又决定页表中的表项,而表项含有页所在页框的物理地址Offset 字段决定页框内的相对位置

  • 用最高10位作为页目录项的索引,将它乘以4,与CR3中的页目录的起始地址相加,获得相应目录项在内存的地址。

  • 从这个地址开始读取32位页目录项,取出其高20位,再给低12位补0,形成页表在内存的起始地址。

  • 用中间的10位作为页表中页表项的索引,将它乘以4,与页表的起始地址相加,获得相应页表项在内存的地址。

  • 从这个地址开始读取32位页表项,取出其高20位,再将线性地址的第11~0位放在低12位,形成最终32位页面物理地址。

  • 10
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值