C++之每日知识树-03-逻辑地址、线性地址、物理地址

打算放弃铁六角而改用铁三角(what、why、how)形式,因为铁六角过于臃肿和牵强,只利用铁三角和三扩展(树根扩展,同枝扩展,枝叶扩展)形式展开。

what:数据总线、地址总线、物理地址、线性地址、逻辑地址
过程:CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线性地址,再利用其页式内存管理单元,转换为最终物理地址

why:为什么CPU需要进行两次地址转换?
这样做两次转换,的确是非常麻烦而且没有必要的,因为直接可以把线性地址抽像给进程。之所以这样冗余,Intel完全是为了兼容而已(Intel为了兼容,将远古时代的段式内存管理方式保留了下来,x86体系的处理器刚开始时只有20根地址线,寻址寄存器是16位。我们知道16位的寄存器可以访问64K的地址空间,如果程序要想访问大于64K的内存,就需要把内存分段,每段64K,用段地址+偏移量的方式来访问,这样使20根地址线全用上,最大的寻址空间就可以到1M字节,这在当时已经是非常大的内存空间了。)。
在这里插入图片描述
how:两次地址转换是如何转换的?
先说一个笼统的过程:CPU在进程调用过程中,每当进程切换时,Linux就会把下一个将要运行进程的页目录表物理内存基地址等信息存放到CR3寄存器中。每个32位的线性地址分为三部分:页目录(高10位)、页表(中间10位)、偏移量(低12位)。页目录地址加上线性地址中页目录存放的页表地址偏移得到页表地址,然后加上线性地址中页表存放的偏移得到相应页的地址(每页大小为12位,4K),最后再加上线性地址中的偏移量得到最终的物理地址。如下图:
在这里插入图片描述
上面乍一看会很蒙圈,下面用图细细的解释一下:
上面说了,地址转换分为两步:将逻辑地址转换为线性地址、将线性地址转换为物理地址。

一、将逻辑地址转换为线性地址

逻辑地址是intel保留下来的根据段式结构格式形成的地址:一个逻辑地址由两部份组成,段标识符: 段内偏移量。比如对于某个函数A,其逻辑地址表示为[A的代码段标识符: 0x08111111]。例如,你在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址偏移,不和绝对物理地址相干。

逻辑地址是在有地址变换功能的计算机中,访内指令给出的地址 (操作数)
叫逻辑地址,也叫相对地址,也就是是机器语言指令中,用来指定一个操作数或是一条指令的地址。

其中段标识符结构如下:

在这里插入图片描述
段选择符中包括对某一个段(代码段、数据段、堆栈段)的描述,包括此段的段基址。、
所以由逻辑地址转换为线性地址过程如下:

在这里插入图片描述

二、由线性地址转化为物理地址
由逻辑地址转化而来的线性地址分为三部分:面目录索引(10位):页表索引(10位):偏移(12位),如下:
在这里插入图片描述
转换过程如下:
在这里插入图片描述
依据以下步骤进行转换:
1、从cr3中取出进程的页目录地址(操作系统负责在调度进程的时候,把这个地址装入对应寄存器);
2、根据线性地址前十位,在数组中,找到对应的索引项,因为引入了二级管理模式,页目录中的项,不再是页的地址,而是一个页表的地址。(又引入了一个数组),页的地址被放到页表中去了。
3、根据线性地址的中间十位,在页表(也是数组)中找到页的起始地址;
4、将页的起始地址与线性地址中最后12位相加,得到最终我们想要的葫芦;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值