栈在虚拟内存和物理内存映射的增长问题

分段

为了解决仅仅使用基址和界限寄存器将进程重定位到物理内存区域,会产生大量的空隙,导致内存没有被有效利用。所以产生了分段的概念,在MMU中,不仅仅一对引入基址和界限寄存器,而是给地址空间内的每个逻辑段一对。一段是地址空间里的一个连续定长的区域。并且只有已用的内存才会在物理内存中分配空间。

一个地址空间

地址空间内存放段

如何引用段


虚拟地址被分为两个部分,第一个部分表示哪个段,第二个部分表示在段内的地址偏移量。如果地址空间内有三个段,那么需要前两位来表示段,剩下的表示偏移。
如上图所示,它指明了第一个段中104(十进制)偏移的位置。
也有隐式的方法来表示,比如硬件可以通过地址的产生方式来确定段。

虚拟地址的地址转换


正向增长的段,其虚拟地址对应的物理地址很好计算。
只需要将偏移量加在Base地址上就行。
对于栈这种增长方向为负的来说,需要先计算段的最大偏移量,比如现在有要访问的虚拟地址是15KB(以最开始的两个图为例),那么它应该映射到物理内存的27KB位置,这个虚拟地址的二进制形式是 11 1100 0000 0000前两位是段的表示,那么后12位则是偏移量的可用区域,可用区域为 11 0000 0000 000011 1111 1111 1111(当然哪些真正可用需要看规定的段的大小)那么最大偏移量为4KB($2^{12}$),由于栈是负增长的,而虚拟地址中的偏移量是表示距离 11 0000 0000 0000的大小,而距离栈的偏移量的Base应该是虚拟地址的偏移量减去4KB,也就是3KB-4KB=-1KB,从而得到27KB。

作者

xiaomaotou31

发布于

2021-09-24

更新于

2021-09-24

许可协议

评论