一、分页存储
- 我的理解是,用户看到的是自己的逻辑地址空间,机器看到的是实际的内存地址空间。两个地址都被划分成小页/块,且大小相等,便于映射。划分成小块是为了更好利用内存,避免大量浪费。可以参考以前的内存分配方式(固定大小连续分配和可变分区连续分配),会产生内碎片和外碎片问题。分页是为了尽量减小这种浪费。
1、基本思想- 用户程序的地址空间被划分为若干固定大小的区域,称为“页”,相应的,内存空间被划分为若干相同大小的块。这样可以将任何一页放到任何一块,实现了离散分离。
2、地址管理
- 用户程序的地址空间被划分为若干固定大小的区域,称为“页”,相应的,内存空间被划分为若干相同大小的块。这样可以将任何一页放到任何一块,实现了离散分离。
- 页的地址组成:页号P + 页内位移量W
- 页号4位,每个作业最多2的4次方=16页,表示页号从00001111,页内位移量的位数表示页的大小,若页内位移量12位,则2的12次方=4k=4096,页的大小为4k,页内地址从0000000000001111 1111 1111
- 若给定一个逻辑地址为A,页面大小为L,则页号P=INT[A/L],页内地址W=A MOD L
3、页表 - 分页系统中,允许将进程的每一页离散地存储在内存的任一物理块中,为了能在内存中找到每个页面对应的物理块,系统为每个进程建立一张页面映射表,简称页表。页表的作用是实现从页号到物理块号的地址映射。比如
页号 物理块号(16进制存储) 存取控制
0 2
1 15(F)
2 14(E)
3 1
4、地址变换
1)程序执行时,从PCB(一般存放在内存的一个连续区域)中取出页表始址和页表长度(4),装入页表寄存器PTR。
-
2)由分页地址变换机构将逻辑地址自动分成页号和页内地址。
D表示10进制,B表示2进制,H表示16进制。
例:11406D=0010|110010001110B=2C8EH
则页号为2,位移量为C8EH=3214D或11406 DIV 4096=2 (页大小是4k,即2^12 = 4096)
11406 MOD 4096=3214
3)将页号与页表长度进行比较(2<4),若页号大于或等于页表长度,则表示本次访问的地址已超越进程的地址空间,产生越界中断。
4)该页表项在页表中的位置。如这里是,页表初始地址 + 2 * 4096 + 3214
5)查页表(页表较小时,可直接放在一个专用寄存器中。较大时需要访问内存,因为这时页表就存放在内存),得到该页号对应的物理块号。 2 14(E)
6)对该页的存取控制进行检查。
-
7)将物理块号送入物理地址寄存器中,再将有效地址寄存器中的页内地址直接送入物理地址寄存器的块内地址字段中,拼接得到实际的物理地址。
例:0010|110010001101B
1110|110010001101B=EC8EH=60558D 或 14*4096+3214=60558D
偏移不变,页号转块号。
最终的结果就是11406D的逻辑地址 变成了 60558D的物理地址。地址偏移不变,页号转块号。
5、 具有快表的地址变换机构
- 分页系统中,CPU每次要存取一个数据,都要两次访问内存(访问页表--页表存放在内存中、以及访问实际物理地址)。为提高地址变换速度,增设一个具有并行查询能力的特殊高速缓冲存储器,称为“联想存储器”或“快表”,存放当前访问的页表项。
二、分段存储
http://blog.chinaunix.net/uid-25100840-id-271102.html
在网上找到了一个比较形象的比喻,挺不错的:
打个比方,比如说你去听课,带了一个纸质笔记本做笔记。笔记本有100张纸,课程有语文、数学、英语三门,对于这个笔记本的使用,为了便于以后复习方便,你可以有两种选择。
第一种是,你从本子的第一张纸开始用,并且事先在本子上做划分:第2张到第30张纸记语文笔记,第31到60张纸记数学笔记,第61到100张纸记英语笔记,最后在第一张纸做个列表,记录着三门笔记各自的范围。这就是分段管理,第一张纸叫段表。
第二种是,你从第二张纸开始做笔记,各种课的笔记是连在一起的:第2张纸是数学,第3张是语文,第4张英语……最后呢,你在第一张纸做了一个目录,记录着语文笔记在第3、7、14、15张纸……,数学笔记在第2、6、8、9、11……,英语笔记在第4、5、12……。这就是分页管理,第一张纸叫页表。你要复习哪一门课,就到页表里查寻相关的纸的编号,然后翻到那一页去复习
第三种,段页结合,结合上面的例子自己想想。
一个例题,某计算机采用二级页表的分页存储管理方式,按字节编址,页面大小为1024B,每个页表项占2B,若逻辑地址空间的大小为 64K 个页面,则表示整个逻辑地址空间的页目录表中包含的表项的个数至少为_______
解析:一页大小为1024B,页表项存的是目录对应的页号,所以一页能存210/2=29个页表项。逻辑地址64K,即216个页面,我需要把这么多的页面都映射到内存块上去,即每一页都对应到一个块。这个对应关系就需要存起来。每一个对应关系都需要存到一个页表项,页表项合起来叫页表。216 / 2^9 = 2^7。所以需要连续的128页来保存页表本身。
在解决这个问题前,我们用类比的方式来举一个例子。
- 假设有一本书,这本书每一页固定大小,最多一页有 1000 个字(页面大小);
- 每一页对应有一个目录中的条目,这个条目用 2 个字表示(页表项大小);
- 那么我 一页纸 就可以写下 1000/2 = 500 个目录条目;
- 现在我整本书有 1000 页(逻辑地址空间大小),我们说了每一页对应一个目录条目,所以有 1000 个目录条目;
- 所以我需要 1000 个目录条目/ 500 个目录条目 = 2 页(注意前面说到了,一页可写 500 个条目。所以我需要 2 个页面来保存目录条目。
6.如果一页太小,比如只能存10个字,那一页就只能放10/2 = 5个目录条目。整本书有1000页,则需要1000/5 = 200页来存放目录条目,是不是太夸张了,想想你会去看一本有200页目录的书吗?所以页的大小需要适中。不然内存空间浪费在存放页表上就太不值得了。