实验二 请求式分页存储管理算法设计与实现

实验请求式分页存储管理算法设计与实现

1.实验内容:模拟请求页式存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO)处理缺页中断;
2.要求:
① 指令序列的设定可以执行拟定,格式如表3;
② 在完成了FIFO换页策略后,可以选做LRU的换页策略,并进行比较;
③ 作业允许的页架数m在不同情况下的缺页中断率;
④ 程序运行时显示地址转变和页面调入调出过程。
3.步骤:
① 设计页表及其数据结构:
页号
标志:是否在主存;
页架号:设定页表在主存的位置;
修改标志:设定页面在主存中是否修改过;
磁盘上位置:设定页面在辅存中的位置;
例如:装入新页置换旧页时,若旧页在执行中没有被修改过,则不必将该页重写磁盘。因此,页表中增加是否修改过的标志,执行“存”指令和“写”指令时将对应的修改标志置成“1”表示修改过,否则为“0”表示未修改过。
表 1 页表格式
|页号 标志 页架号 修改标志 在磁盘上位
②设计一个地址转换程序半模拟硬件的地址转换和缺页中断。
当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可以输出转换后的绝对地址来表示一条指令已执行完成。当访问的页不在主存中时,则输出“*页号”来表示硬件产生了一次缺页中断。模拟地址转换流程见图1.1。
③ 设计FIFO页面调度程序;
FIFO页面调度算法总是先调出作业中最先进入主存中的哪一页。因此可以用一个数组来表示(或构成)页号队列。数据中每个元素是该作业已在主存中的页面号,假定分配给作业的页(架)数为m,且该作业开始的m页已装入主存,则数组可由m个元素构成。
P[0],P[1],P[2],…,P[m-1]
它们的初值为P[0]:=0,P[1]:=1,P[2]:=2,…,P[m-1]:=m-1
用一指针K指示当要调入新页时应调出的页在数组中的位置,K的初值为“0”,当产生缺页中断后,操作系统总是选择P[K]所指出的页面调出,然后执行。
④ 设计输入数据和输出格式;
如: 假定主存中页架大小为1024个字节,现有一个共7页的作业,其副本已在磁盘上。系统为该作业分配了4个页架,且该作业的第0页至第3页已装入内存,其作3页未主存,该作业的页表如下:

页号 标志 页架号 修改标志 在磁盘上位置
0 1 5 0 011
1 1 8 0 012
2 1 9 0 013
3 1 1 0 021
4 0 0 022
5 0 0 023
6 0 0 121
如果该作业依次执行的指令序列如附表3所示:
操作 页号 页内地址 操作 页号 页内地址

  • 0 070 移位 4 053
    - 1 050 + 5 023
    × 2 015 存 1 037
    存 3 021 取 2 078
    取 0 056 + 4 001
    - 6 040 存 6 084
    依次执行上述指令调试你所设计的程序(仅模拟指令的执行,不考虑序列中具体操作的执行)。
    ⑤ 编程上机,验证结果。
    4.实验报告:
    为进一步考察程序的执行,可自行确定若干组指令,运行程序,核对执行结果实验报告:
    ① 实验题目;
    ② 程序中所用的数据结构及说明;
    ③ 打印一份源程序并附上必要的说明;
    ④ 按照指令的执行序列,打印输出结果:绝对地址或调出、调入的页号。
    P[K]:=要装入的新页页号
    K:=(k+1)mod m
    在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT调出的页号”和“IN要装入的新页页号”来模拟一次调出和装入过程,模拟程序的流程图见附图1.1。

按流程控制过程如下:
提示:输入指令的页号和页内偏移和是否存指令 ,若d为-1则结束,否则进入流程控制过程,得P1和d,查表在主存时绝对地址P1×1024+d

在这里插入图片描述
大概实验指导书就是这样,自己根据网上的代码和自己的实验指导书进行了编写,实验当中出现的问题还是比较多的,这个代码大家使用的时候注意一下可以直接在结构体后面,直接给数组赋值,我开始写的时候比较凌乱一些。不过结果是对的

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
#include<math.h>
# include<iostream.h>
# define N 1000
struct zhiling
{
    char caozuo[5];//操作
	int yehao1;//页号
	int yeneidizhi;//页内标志
}zhiling[N]={{"+",0,70},{"-",1,50},{"*",2,15},{"cun",3,21},{"qu",0,56},{"-",6,40},{"yi",4,53},{"+",5,23},{"cun",1,37},{"qu",2,78},{"+",4,1},{"cun",6,84}};
 struct yebiao
{
	int yehao;//页号
	int biaozhi;//标志
	int yejiahao;//页架号
	int xiugaibiaozhi;//修改标志
	int cipanweizhi;//磁盘位置
}yebiao[N];
int p[4]={0,1,2,3};//装入主存的页号(用数组装入)

void init()//页表的初值化
{
	int i;
	for(i=0;i<4;i++)
	{
		yebiao[i].yehao=i;
		yebiao[i].biaozhi=1;
		yebiao[i].xiugaibiaozhi=0;
	}//标志前四个页号在主存当中将标志置为1,修改标志为0;
	for(i=4;i<8;i++)
	{
		yebiao[i].yehao=i;
		yebiao[i].biaozhi=0;
		yebiao[i].xiugaibiaozhi=0;
	}//标志后三个的页号不在主存当中将标志置为0,修改标志为0;
	yebiao[0].yejiahao=5;
    yebiao[1].yejiahao=8;
    yebiao[2].yejiahao=9;
    yebiao[3].yejiahao=1;//对0—3的页号设定页架号,即(设定页表在主存的位置)
	yebiao[4].yejiahao=-1;
	yebiao[5].yejiahao=-1;
	yebiao[6].yejiahao=-1;//将没有设定页架号的页架号都设定为-1,便于后面的交换
	yebiao[0].cipanweizhi=11;
    yebiao[1].cipanweizhi=12;
    yebiao[2].cipanweizhi=13;
    yebiao[3].cipanweizhi=21;
    yebiao[4].cipanweizhi=22;
    yebiao[5].cipanweizhi=23;
    yebiao[6].cipanweizhi=21;//对于0—6的页号的磁盘位置赋值(设定页表在辅存当中的位置)
}
/*void init2()//指令序列的初值化
{
	int j;
	for(j=0;j<12;j++)

	zhiling[0].caozuo[5]='+';
	zhiling[1].caozuo[5]='-';
	zhiling[2].caozuo[5]='*';
	strcpy((char *)&zhiling[3].caozuo[5],"c");
	strcpy((char *)&zhiling[4].caozuo[5],"q");
	zhiling[5].caozuo[5]='-';
    strcpy((char *)&zhiling[6].caozuo[5],"y");
	zhiling[7].caozuo[5]='+';
    strcpy((char*)&zhiling[8].caozuo[5],"c");
    strcpy((char*)&zhiling[9].caozuo[5],"q");
	zhiling[10].caozuo[5]='+';
    strcpy((char*)&zhiling[11].caozuo[5],"c");//对于操作进行初始化
	zhiling[0].yehao1=0;
	zhiling[1].yehao1=1;
	zhiling[2].yehao1=2;
	zhiling[3].yehao1=3;
	zhiling[4].yehao1=0;
	zhiling[5].yehao1=6;
	zhiling[6].yehao1=4;
	zhiling[7].yehao1=5;
	zhiling[8].yehao1=1;
	zhiling[9].yehao1=2;
	zhiling[10].yehao1=4;
	zhiling[11].yehao1=6;//对于页表号进行初始化
	
    zhiling[0].yeneidizhi=70;
    zhiling[1].yeneidizhi=50;
    zhiling[2].yeneidizhi=15;
    zhiling[3].yeneidizhi=21;
    zhiling[4].yeneidizhi=56;
    zhiling[5].yeneidizhi=40;
    zhiling[6].yeneidizhi=53;
    zhiling[7].yeneidizhi=23;
    zhiling[8].yeneidizhi=37;
    zhiling[9].yeneidizhi=78;
    zhiling[10].yeneidizhi=01;
    zhiling[11].yeneidizhi=84;//对于页内地址进行初始化
}*/


void print1()//输出页表
{
	cout<<"*********************作业的页表*********************"<<endl;
	int i;
	for(i=0;i<7;i++)
	{
		cout<<"  页号  "<<yebiao[i].yehao;
		cout<<"  页内标志  "<<yebiao[i].biaozhi;
		cout<<"  页架号  "<<yebiao[i].yejiahao;
		cout<<"  修改标志  "<<yebiao[i].xiugaibiaozhi;
		cout<<"  磁盘位置  "<<yebiao[i].cipanweizhi;
		cout<<endl;
	}
}
void print2()//输出执行的指令
{
		cout<<"*********************作业的执行指令*********************"<<endl;
	int i;
	for(i=0;i<12;i++)
	{
		cout<<" 操作  "<<zhiling[i].caozuo[5];
		cout<<" 页号  "<<zhiling[i].yehao1;
		cout<<" 页内标志  "<<zhiling[i].yeneidizhi;
		cout<<endl;
	}
}

void zhuanhuan()//输出作业执行调度算法,先入先出算法
{
	cout<<"*********************作业的执行*********************"<<endl;
	int i;
    int biaozhi1,
		jiaohuanyehao,
		yehao3,xiugaibiaozhi1;//定义一个临时的变量,标志,交换页号,页号
    int k=0;//定义数组的头
    int m=4;//定义数组的长度
    long jueduidizhi;
    for(i=0;i<12;i++)//作业执行指令序列,12个
	{
      yehao3=zhiling[i].yehao1;//yehao3等于指令操作对的页号
      biaozhi1=yebiao[yehao3].biaozhi;//biaozhi1是yehao3对应的标志标志是否在内存
	  cout<<"操作为  "<<zhiling[i].caozuo<<"页号为  "<<zhiling[i].yehao1<<"页内标志为  "<<zhiling[i].yeneidizhi<<endl;//执行的指令序列为
	  cout<<"页号  "<<yehao3<<"中执行"<<endl;//yehao3执行
      if(biaozhi1==1)//如果标志等于1则证明在内存当中形成绝对地址
	  {
		  jueduidizhi=yebiao[yehao3].yejiahao*1024+zhiling[i].yeneidizhi;//绝对地址=内存页架号*页架的大小+页内地址
		 
		  if(zhiling[i].caozuo=="cun")//判断是否是存指令
		  {
			  yebiao[yehao3].xiugaibiaozhi=1;//是则修改标志置为1
			  cout<<"绝对地址是   "<<jueduidizhi<<endl;//输出绝对地址

		  }
		  else
		  {
			   cout<<"绝对地址是  "<<jueduidizhi<<endl;//不是则直接输出绝对地址   
		  }

	  }
	  if(biaozhi1==0)//如果标志位不是1的时候直接输出*页号
	  {
		  cout<<"页号 *"<<yehao3<<endl;//如果页号不在主存块当中输出*页号表示发生了中断
		  jiaohuanyehao=p[k];//队列的头指针;
		  cout<<"把页号为  "<<jiaohuanyehao<<" 置换"<<endl;
		  xiugaibiaozhi1=yebiao[jiaohuanyehao].xiugaibiaozhi;
		  if(xiugaibiaozhi1==1)//执行指令的页号的修改位判断
		  {
			  cout<<"调出的页号为  "<<jiaohuanyehao<<endl;//修改位是1输出要置换的页号
			  cout<<"要装入的新页页号  "<<yehao3<<endl;
		  }
		  else
		  {
			  cout<<"要装入的新页页号  "<<yehao3<<endl;//修改位是0,输出要进入的新的页表
		  }
		                            
		  yebiao[yehao3].biaozhi=yebiao[jiaohuanyehao].biaozhi;  //交换标志是否在主存当中
		  yebiao[yehao3].yejiahao=yebiao[jiaohuanyehao].yejiahao;
	      yebiao[jiaohuanyehao].yejiahao=-1;
		  yebiao[jiaohuanyehao].biaozhi=0;
          p[k]=yehao3;
	      k=(k+1)%m;//数组队列向前走
		  yebiao[jiaohuanyehao].xiugaibiaozhi=0;
		  yebiao[yehao3].xiugaibiaozhi=1;
	  }
	}
}

       
void main()
{
    init();
    //init2();
	print1();
	print2();
	zhuanhuan();
}

  • 14
    点赞
  • 155
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值