在编译时为什么使用分页会导致覆盖问题?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/klli15/article/details/100524343

在编译时为什么只使用分页模式会导致覆盖问题

这个问题困扰了我一天,结果在第二天早上醒来就想通了。
一切的一切,记得一句话 分页的虚拟地址是一维的,分段的虚拟地址是二维的

一维?二维?

我的理解是,一维就是经过一次映射后获得的地址,分页模式的虚拟地址是 页号x+页内偏移y,地址转换过程是:

  1. 页号x 到页表查,获取到实际的物理页a地址
  2. 实际地址是 物理页地址a+页内偏移y,注意这里是拼接,而不是加法

二维就是经过两次映射后获得的地址,分段模式中的段页式的虚拟地址就是二维的,格式为段号 d + 段内偏移 y地址转换的过程是:
3. 凭 段号 d去段表查询,得到 页号x
4. 凭 页号x 到页表查,获取到实际的物理页a地址
5. 实际地址是 物理页地址a+页内偏移y

分页
分页地址格式分页

分段
分段

更多请参考 :链接

问题提出

碰撞问题
这里我一直看不懂,为什么会发生碰撞或者称为覆盖问题?

原因解析

  1. 编译器在编译程序的时候,只分配虚拟地址,此时与分页或者分段模式没有一点关系,这是编译器的事

  2. 编译器会给予各种段一个基址——即所有段内的地址都是基于这个地址进行偏移。比如:数据段的基址是 0xA,代码段的基址是0xB,栈段的基址是 0xC

  3. 随着编译的不断进行,各个段都不断增加内容,他们往同一个方向增长。当某一个段的数据增长特别多,就会触及上一个段的内容,就会导致一个虚拟地址对应两个内容:一个是 基址1+偏移量 1,一个是基址2+偏移量2,当偏移量2比偏移量1大很多的时候,就会导致覆盖问题。

    简单运算一下,假设 base1+offset1 <= base2+offset2 => offset2-offset1 >= base1-base2 ,就是说当偏移量2比偏移量1相差 base1 - base2就会导致覆盖/重叠问题。

  4. 当分页模式的时候就会把 base1+offset1 当作一个虚拟地址,然后查页表,当位移过大的时候就会侵略到其他段了。

    如 页面大小为 64k,虚拟地址A为 1 + 65k ,虚拟地址B为 2 + 0k 由于 65k > 64k ,所以就会接触了 第 2页里面的内容了

  5. 当分段模式的时候,有以下几个因素可以保证其不会出现重叠/覆盖问题:
    5.1. 段有大小,如果超过段则会报段溢出
    5.2 不同的段会映射到不同的页表,就是不同的段压根他们不会在同一张页表,所以即使 offset2 - offset1 > 页面大小 也没关系,因为他们不在同一张页表

猜你喜欢

转载自blog.csdn.net/klli15/article/details/100524343
今日推荐