段页式存储


几乎每一本将操作系统原理的书籍都会谈及内存管理方法的段页式存储。以前看书都是看的云里雾里!原因就是还没有懂INTEL指令,不知道页式存储有什么作用。国内教材有个最大的弊病就是,作者通常先将概念,然后再将如何运用,很少去提及概念是如何被提出来!为什么非要提出这样一个概念。

除非你已经被一个问题困扰到茶饭不思、辗转难眠,否则你绝对不会明白一个新的概念对你有多大的作用

分段还是分页其实不是两个不同的概念!分段,其中心思想是将程序分成若干的逻辑段,每个段实现什么功能,提供什么资源。这个其实和后来面向对象的类的思想没有任何区别,仅仅是表现不一样罢了。在过去编程时,将程序分为若干逻辑段(数据段,32位代码段,16位代码段等),然后通过设置CS来实现段之间的跳转。这种方式使得程序在设计期间逻辑清晰。但是这种方式,程序是一个线性的指令集合,某些时候,人们需要同时执行两个任务,采用分段需要频繁的切换CS,这样造成很大的性能损耗。INTEL为了满足这种能够新增加一组寄存器 CR0、1、2、3来实现任务跳转。这个使用同样一个逻辑地址就能定位为不同的物理地址,如下图

                            如何分页

请思考如下一个数学题

y=f(x)    {x的定义域为[0,π/2]}  ,找到一个函数使得f(x)的值域为[0,1]?

如果你学过三角函数马上就会想到 f(x)=sin(x) 

用在分页机制里,该数学题变为了

y=f(x)    {x的定义域为[0,4.4M] 用4.4M的虚拟地址范围 },找到一个函数使得f(x)的值域为[0,4G]---32位CPU内存寻址范围?

解析:

这里当然可以使用一个函数来实现这种扩展,但是在计算机里面,没有使用函数,而是使用索引的方式来表示一个更大的范围,所谓索引,就是新华字典里面的查询页!一本字典那么厚,但是可以使用几页查询页就能找到字典里面的任何一个字!

在INTEL x86CPU保护模式里,一页通常值为4K(4K=2的12次方,需要12位来表示页内偏移地址),所以4G就是1M(1M=2的20次方)个4K,1M个页索引。这样一个物理地址就可以转化为

20位页索引+12位页内:需要用1M个索引项去记录每一页的属性!INTEL为了减小1M这个值,又将1M索引再次来个索引,将1M个索引按照1K个索引为1段,总共就是1K段!这样一个屋里地址就转化为:

10位页索引的索引+10位页索引+12位页内偏移地址,使用两级索引来表示一个地址,地址转换过程如下:

,表中的每一项也就是每一个索引叫做页表项PTE(page table entry)

10位页索引的索引的所有集合(1K个)有个专门的名字:,表中的每一项也就是每一个索引的索引叫做页目录表项PDE(page directory entry)

有一点值得强调,页表项和页目录表项不仅仅只有索引,只是上面为了理解简单而省略一些信息,他们都有各种的属性!

每个项需要4个字节,总共就需要 4*1K(1K个页目录表项)+4*(1M个页表项) = 4.4M!

实际上启动分页的过程,也就是将在内存中初始化f(x)的一个过程!具体而言就是在内存中为每一个物理页做索引,加属性的过程!

当这些信息都被正确的在内存中初始化完毕之后,最重要的一步,就可以,然后将CR0最高位设置为1就表示启动了分页机制!

分页还是不分页,分段还是不分段,保护模式还是实模式追索到源头其实就是对CPU指令集的一个应用,CPU提供了某些功能,然后由此编写的操作系统就启用这些功能!所以不是操作系统多么牛逼,而是处理器多么厉害

详细解读一下这句话:

此时你看看下面这张图:

ax, SelectorPageDir ecx, eax, loop . ax, SelectorPageTbl ecx, * eax, loop . short .

相关内容