logo资料库

模拟分页式存储管理中硬件的地址转换和产生缺页中断。.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
模拟分页式存储管理中硬件的地址转换和产生缺页中断 一、实验目的 在计算机系统中,为了提高主存利用率,往往把辅助存储器(如 磁盘)作为主存储器的扩充,使多道运行的作业的全部逻辑地址空间 总和可以超出主存的绝对地址空间。用这种办法扩充的主存储器称为 虚拟存储器。通过本实验帮助同学理解在分页式存储管理中怎样实现 虚拟存储器。 二、实验要求及实验环境 第一题:模拟分页式存储管理中硬件的地址转换和产生缺页中 断。分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业 被选中时,可把作业的开始几页先装入主存且启动执行。为此,在为 作业建立页表时,应说明哪些页已在主存,哪些页尚未装入主存。 作业执行时,指令中的逻辑地址指出了参加运算的操作存放的页 号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为 “1”,则表示该页已在主存,这时根据关系式“绝对地址=块号×块 长+单元号”计算出欲访问的主存单元地址。如果块长为 2 的幂次, 则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而 成绝对地址。若访问的页对应标志为“0”,则表示该页不在主存,这 时硬件发“缺页中断”信号,有操作系统按该页在磁盘上的位置,把 该页信息从磁盘读出装入主存后再重新执行这条指令。设计一个“地 址转换”程序来模拟硬件的地址转换工作。当访问的页在主存时,则 形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代 替一条指令的执行。当访问的页不在主存时,则输出“* 该页页号”, 表示产生了一次缺页中断。 第二题:用先进先出(FIFO)页面调度算法处理缺页中断。 在分页式虚拟存储系统中,当硬件发出“缺页中断”后,引出操 作系统来处理这个中断事件。如果主存中已经没有空闲块,则可用 FIFO 页面调度算法把该作业中最先进入主存的一页调出,存放到磁 盘上,然后再把当前要访问的页装入该块。调出和装入后都要修改页 表页表中对应页的标志。 FIFO 页面调度算法总是淘汰该作业中最先进入主存的那一页, 因此可以用一个数组来表示该作业已在主存的页面。假定作业被选中 时,把开始的 m 个页面装入主存,则数组的元素可定为 m 个。 编制一个 FIFO 页面调度程序,为了提高系统效率,如果应淘汰 的页在执行中没有修改过,则可不必把该页调出(因在磁盘上已有副 本)而直接装入一个新页将其覆盖。由于是模拟调度算法,所以,不 实际启动输出一页和装入一页的程序,而用输出调出的页号和装入的 页号来代替一次调出和装入的过程。 三、设计思想(本程序中的用到的所有数据类型的定义,主
程序的流程图及各程序模块之间的调用关系) 1.程序流程图 以下为 FIFO 算法流程:
2 .逻辑设计 使用线性表保存页表。每个节点信息包括调入主存的标志,主 存块号,在磁盘上的位置,修改标志等。使用线性表保存 FIFO 算法 使用的对应关系数组 P,用数组模拟实现调度的队列。该队列需支持 查找,插入和删除操作(即替换操作)。 3、物理设计 全局定义如下: struct info//页表 { bool flag; //标志 long block;//块号 long disk;//在磁盘上的位置
bool dirty;//修改标志 }pagelist[SizeOfPage]; long po;//队列标记 long P[M]; 使用函数 init()进行初始化,使用循环结构读入各条指令。 四、测试结果 实际运行的结果如下: 请选择题号(1/2):1 请输入指令的页号和单元号: 0 70 绝对地址=710 请输入指令的页号和单元号: 4 053 * 4 请输入指令的页号和单元号: 1 50 绝对地址=1074 请输入指令的页号和单元号: 5 023 * 5 请输入指令的页号和单元号: 2 15 绝对地址=1167 请输入指令的页号和单元号: 1 037 绝对地址=1061 请输入指令的页号和单元号: exit 请选择题号(1/2):2 请输入指令的页号、单元号,以及是否为存指令: 0 70 N 绝对地址=710 请输入指令的页号、单元号,以及是否为存指令: 4 053 N out 0 in 4 请输入指令的页号、单元号,以及是否为存指令: 1 50 N 绝对地址=1074 请输入指令的页号、单元号,以及是否为存指令: 5 023 N out 1 in 5
请输入指令的页号、单元号,以及是否为存指令: 2 15 N 绝对地址=1167 请输入指令的页号、单元号,以及是否为存指令: 1 037 y out 2 in 1 请输入指令的页号、单元号,以及是否为存指令: 3 21 Y 绝对地址=149 请输入指令的页号、单元号,以及是否为存指令: 2 078 N out 3 in 2 请输入指令的页号、单元号,以及是否为存指令: 0 56 N out 4 in 0 请输入指令的页号、单元号,以及是否为存指令: 4 001 N out 5 in 4 请输入指令的页号、单元号,以及是否为存指令: 6 40 N out 1 in 6 请输入指令的页号、单元号,以及是否为存指令: 6 084 Y 绝对地址=1236 请输入指令的页号、单元号,以及是否为存指令: exit 数组 P 的值为: P[0]=0 P[1]=4 P[2]=6 P[3]=2 五、系统不足与经验体会 系统的不足包括健壮性尚不够好,界面比较简单,对页表的 初始化需要修改程序。 经验体会:注意体会算法的精神,程序前后逻辑要一致。注 意测试时数据的全面性。 六、附录:源代码(带注释) #include
#include #define SizeOfPage 100 #define SizeOfBlock 128 #define M 4 struct info//页表 { bool flag; //标志 long block;//块号 long disk;//在磁盘上的位置 bool dirty;//修改标志 }pagelist[SizeOfPage]; long po;//队列标记 long P[M]; void init_ex1() { memset(pagelist,0,sizeof(pagelist)); pagelist[0].flag=1; pagelist[0].block=5; pagelist[0].disk=011; pagelist[1].flag=1; pagelist[1].block=8; pagelist[1].disk=012; pagelist[2].flag=1; pagelist[2].block=9; pagelist[2].disk=013; pagelist[3].flag=1; pagelist[3].block=1; pagelist[3].disk=021; } void work_ex1() { bool stop=0; long p,q; char s[128]; do { printf("请输入指令的页号和单元号:\n"); if (scanf("%ld%ld",&p,&q)!=2) { scanf("%s",s); if (strcmp(s,"exit")==0) { stop=1; }
} else { if (pagelist[p].flag) { printf("绝对地址=%ld\n",pagelist[p].block*SizeOfBlock+q); } else { printf("* %ld\n",p); } } }while (!stop); } void init_ex2() { po=0; P[0]=0;P[1]=1;P[2]=2;P[3]=3; memset(pagelist,0,sizeof(pagelist)); pagelist[0].flag=1; pagelist[0].block=5; pagelist[0].disk=011; pagelist[1].flag=1; pagelist[1].block=8; pagelist[1].disk=012; pagelist[2].flag=1; pagelist[2].block=9; pagelist[2].disk=013; pagelist[3].flag=1; pagelist[3].block=1; pagelist[3].disk=021; } void work_ex2() { long p,q,i; char s[100]; bool stop=0; do { printf("请输入指令的页号、单元号,以及是否为存指令:\n"); if (scanf("%ld%ld",&p,&q)!=2) { scanf("%s",s); if (strcmp(s,"exit")==0)
{ stop=1; } } else { scanf("%s",s); if (pagelist[p].flag) { printf("绝对地址=%ld\n",pagelist[p].block*SizeOfBlock+q); if (s[0]=='Y' || s[0]=='y') { pagelist[p].dirty=1; } } else { if (pagelist[P[po]].dirty) { //将更新后的内容写回外存 pagelist[P[po]].dirty=0; } pagelist[P[po]].flag=0; printf("out %ld\n",P[po]); printf("in %ld\n",p); pagelist[p].block=pagelist[P[po]].block; pagelist[p].flag=1; P[po]=p; po=(po+1)%M; } } }while (!stop); printf("数组 P 的值为:\n"); for (i=0;i
分享到:
收藏