16章 分段

目录

分段:泛化的基址/界限

我们引用哪个段

栈怎么办

支持共享

细粒度与粗粒度的分段

操作系统支持

小结


        在分段技术之前,了解了基址和界限寄存器,但是这个东西,将不同的进行重定位到不同的物理内存区域。对于这些区域的堆,栈中间,会发现有一大块没有用到的空间,但却占用了物理内容,所以这个技术有下面两个问题:

  • 大大浪费了内存空间

  • 导致物理内存无法连续起来,无法为后面的程序提供完整的地址空间

分段:泛化的基址/界限

        在这个时候出现了分段的技术:这里不只是有一个基址和界限寄存器,而且是有很多对的,是怎么使用的?当我们使用的时候,可以将这些段放在不同的物理地址,所以这样就不浪费物理资源。大概意思就是这样

        这里如果计算虚拟地址4200的话,应该是要4200-4096=104,这个计算的是偏移量,然后用这个加上基址寄存器的物理地址34KB,得到真正的物理地址,这样就可以计算是否超出边界。

        对于这种计算需要牢记于心

        段错误:在支持分段的机器上发生了非法的内存访问。

我们引用哪个段

        那么在地址转换的时候怎么使用段寄存器,以及如何知道段内偏移量,还有引用了哪一个段?提出了两种方法:

  • 显示方式

在前面的图中,可以看到有堆栈,代码三个段,所以使用14位虚拟地址的前两位来表示在哪个段,

  • 00:表示代码段

  • 01:表示堆地址

  • 11:表示栈地址

就是这样,后面的就都表示段内的偏移地址了。这样的话,就很容易判断是否超出界限了。依旧是需要使用基址和偏移量进行相加的。

在计算机体系结构中,虚拟地址的位数是由体系结构设计者决定的,而不是固有的属性。通常情况下,虚拟地址的位数与CPU的寻址能力以及内存管理单元(MMU)的设计有关。

关于为什么选择14位虚拟地址的一个可能的解释是,在某些体系结构中,14位虚拟地址可以提供足够的地址空间来满足大多数应用程序的需求,同时又不会增加太多的额外开销。过小的虚拟地址位数可能导致地址空间不足以支持大型应用程序,而过大的虚拟地址位数则可能增加内存管理的复杂性和开销。

当然,这只是一个例子。实际上,虚拟地址的位数可能会根据特定的计算机体系结构和设计需求而有所不同。

  • 隐式方式

硬件通过地址产生的方式确定段,例如:如果地址由程序计数器产生(即它是指令获取),那么地址

在代码段。如果基于栈或基址指针,它一定在栈段。其他地址则在堆段。

栈怎么办

在图中可以看出来栈是反向增长的。

都知道是反向增长,那么具体是怎么样的呢?

首先通过前两位来制定段,然后假设要处理3KB,要用3KB减去最大的段地址,然后用这个数(反向偏移量)再加上基址,这样就得到真正的物理地址,然后方便与检查,确保反向偏移量的绝对值小于段的大小。

支持共享

在分段技术的推进下,发现可以通过共享空间,来提高效率,比如代码段,就是需要其他的也能看到,所以推出了保护位,这个限制了其他的进程能否查看。虽然他们觉得自己独占了空间,其实不是的。

这样的话,物理内存的一个段可以映射到多个虚拟地址空间,那么之前判断是否非法访问的算法也就是要改变了,这下在地址超出的时候,还是要检查特定访问是否允许。

细粒度与粗粒度的分段

粗粒度:也就是将地址空间分成较大的块

细粒度:与之相反,划分为大量较小的段

但是分的段多了的话,就会需要硬件进一步支持,这样就出现了段表,它支持创建非常多的段。更加方便的去利用内存了。

操作系统支持

系统运行时,地址空间中的不同段被重定位到物理内存中。栈和堆之间没有使用的区域就不需要再分配物理内存,让我们能将更多地址空间放进物理内存。但是有两个问题:

  1. 各个段寄存器中的内容必须保存和恢复。显然,每个进程都有自己独立的虚拟地址空间,操作系统必须在进程运行前,确保这些寄存器被正确地赋值。

  2. 管理物理内存的空闲空间。新的地址空间被创建时,操作系统需要在物理内存中为它的段找到空间。之前,我们假设所有的地址空间大小相同,物理内存可以被认为是一些槽块,进程可以放进去。现在,每个进程都有一些段,每个段的大小也可能不同。但是这样的话会出现一些空闲的空洞内存,无法分配给新的段,或者扩大已有段,被称为外部碎片。

解决方法:

  1. 紧凑物理内存,安排原有的段。就是先终止进程,将数据复制到连续的内存去,改变段寄存器的值,然后指向新的物理地址。但是这样存本比较高,因为拷贝段是内存密集型的,一般会占用大量的处理器时间。

  2. 利用空间列表管理,里面涉及到的算法比较多,可以去搜,就是试图保留大的内存块用于分配。

小结

分段解决了一些问题,帮助我们实现了更高效的虚拟内存。不只是动态重定位,通过避免地址空间的逻辑段之间的大量潜在的内存浪费,分段能更好地支持稀疏地址空间。它还很快,因为分段要求的算法很容易,很适合硬件完成,地址转换的开销极小。分段还有一个附加的好处:代码共享。如果代码放在独立的段中,这样的段就可能被多个运行的程序共享。

但我们已经知道,在内存中分配不同大小的段会导致一些问题,我们希望克服。首先,是我们上面讨论的外部碎片。由于段的大小不同,空闲内存被割裂成各种奇怪的大小,因此满足内存分配请求可能会很难。用户可以尝试采用聪明的算法[W+95],或定期紧凑内存,但问题很根本,难以避免。

第二个问题也许更重要,分段还是不足以支持更一般化的稀疏地址空间。例如,如果有一个很大但是稀疏的堆,都在一个逻辑段中,整个堆仍然必须完整地加载到内存中。换言之,如果使用地址空间的方式不能很好地匹配底层分段的设计目标,分段就不能很好地工作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值