页表地址是真实地址吗?

最近有空又看了下页表原理(页表,永远的痛),很多博客都写得很好,都是一套一套的,什么cpu不直接访问内存啊,什么mmu协助转换虚拟地址,什么虚拟地址转真实地址计算算法,都很对,但是很少人提到一个问题并且作详细解答,页表本身怎么存取的?不是指整个页表的结构怎么存储,页表项又是怎么摆放,而是说,页表放在内存哪里?放在真实内存的哪里?怎么访问的?cpu访问页表的时候用的是虚拟地址吗?如果是,那逻辑不就死循环了吗......

cpu访问虚拟内存 --->

需要查询页表转换真实地址---->

访问页表所在内存 ---->

需要查询页表从而求出页表自己的真实地址---->???

我访问页表所在地址的前提是先从页表中找到页表自己的真实地址?

后来查了一下,综合结论是 (没看错的话): 有一个叫CR3的寄存器,专门存放的是当前进程页表的真实物理地址。否则就会出现上述的蛋生鸡问题。另外,CR0寄存器中的特别位置可以控制CPU是否进入实模式,以及是否在保护模式中禁用MMU(现代系统一般跑在保护模式下),从而可以直接访问内存真实物理地址。更多细节后续再补。

初步研究补充(2021/3/14):其实CPU访问内存这个问题应分成两个角度去看,一个是用户,一个是cpu自己。对于用户,他使用到的cpu提供的访问内存指令,比如mov ax, [0x1234]等指令,是没必要关心虚不虚,真不真实的地址的,包括在编写实模式代码时(实模式cpu访问某地址是直接找到真实地址的)。只要你在实模式跑,你叫cpu访问的地址就是真实地址。如果用户切成保护模式,把某个开关开了,那么这时的cpu访问某个地址之前,自己进行地址转换,无需cpu外部用户参与。可以这么理解:cpu把地址转换的逻辑封装在内部了,只要用户在启动系统时,在进入保护模式之前,在引导程序里面,把各种诸如GDT,IDT,页表等的关键表给在某个真实地址里面初始化好,然后把这个真实地址的值塞到对应的寄存器中(CR*),那么,进入保护模式之后,cpu执行提供给外部用户的访问内存的指令时,会跑自己的微指令去执行转换逻辑,而cpu自己在任意时候都能访问内存的真实地址,只是这些操作对外部用户不可见。所以有个说法很有问题:在保护模式里面,CPU访问的都是虚拟地址。它把CPU对外服务跟内部真实执行模糊了。这句对于CPU提供给外部用户的指令集来说是对的,也就是各种如mov等能寻址的指令,他们在保护模式下确实是虚地址。但是到了CPU内部,跑那个地址转换的流程时,CPU是需要访问真实地址的。它的步骤大概如下:1:从特殊寄存器中拿到各种表地址(真实地址)  2:访问这些表的真实地址获取表内信息(如访问页表获取转换地址)  3:根据规制合成真实地址   4:访问改真实地址(如果有)或者报错中断(缺页中断)找中断表走错误处理逻辑。  整个流程下来,CPU至少访问两次真实地址,所以不分情况讨论对外提供的服务还是内部执行逻辑便得出“CPU访问的都是虚拟地址”就是在瞎扯。

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值