页式虚拟FIFO与LRU存储管理缺页中断的模拟算法并计算对应的物理地址.docx
《页式虚拟FIFO与LRU存储管理缺页中断的模拟算法并计算对应的物理地址.docx》由会员分享,可在线阅读,更多相关《页式虚拟FIFO与LRU存储管理缺页中断的模拟算法并计算对应的物理地址.docx(22页珍藏版)》请在冰点文库上搜索。
页式虚拟FIFO与LRU存储管理缺页中断的模拟算法并计算对应的物理地址
页式虚拟FIFO与LRU存储管理缺页中断的模拟算法并计算对应的物理地址
FIFO
一课程设计目的与功能
1目的
通过分析、设计和实现页式虚拟存储管理缺页中断的模拟系统,熟悉和掌握请求分页式存储管理的实现过程,重点掌握当请求页面不在内存而内存块已经全部被占用时的替换算法,熟悉常见替换算法的原理和实现过程,并利用替换算法的评价指标——缺页次数和缺页率,来对各种替换算法进行评价比较。
设计并实现出的结果程序要能够很好地显示页面调入和替换详细信息。
请求分页的具体实现过程如图
请求分页流程图
数据结构
typedefstructpage
{
//进程的虚页总数
inttaskPageNum;
//系统为程序分的内存块数
intmemoryPageNum;
//装入位标志
intisMemory;
//页内偏移
intpageOffset;
//其他
intinfo;
}page;
三源程序的主要部分
1main函数
voidmain()
{
inti=0;
printf("请输入1进入FIFO算法:
\n输入2进入LRU算法\n");
scanf("%d",&i);
if(i==1)
FIFO();
else
LRU();
}
替换算法实现函数
//先进先出算法
四运行结果与运行情况分析
待调入页面数:
5
可用物理块数:
3
页面请求序列
01341203;
默认情况是将0号页面已调入内存
1FIFO算法
运行结果,如图:
2LRU算法
运行结果,如图:
结论
通过测试运行,可以看出结果程序能满足设计要求,提示用户对对输入进行限制,并提示用户输入选择算法,按照不同的替换算法处理并且显示请求页面的调入和替换情况。
附录
#include
#include
#definepage_size1024
#definebase_address3000
typedefstructpage
{
//进程的虚页总数
inttaskPageNum;
//系统为程序分的内存块数
intmemoryPageNum;
//装入位标志
intisMemory;
//页内偏移
intpageOffset;
//其他
intinfo;
}page;
//先进先出算法
voidFIFO()
{
intflag=0;
intmid_temp;
inttaskNum;
inttaskpage;
intmemoryBlockNum;
inttask_offset;
intmemory_block;
printf("请输入虚页总数:
\n");
scanf("%d",&taskNum);
printf("请输入内存块数目:
\n");
scanf("%d",&memoryBlockNum);
memory_block=memoryBlockNum;
//动态定义数组
page*p=(page*)malloc(taskNum*sizeof(page));
//对结构体初始化
for(inti=0;ip[i].taskPageNum=i,
p[i].isMemory=0,
p[i].memoryPageNum=-1,
p[i].pageOffset=-1;
//首先装入0号页
p[0].isMemory=1;
p[0].memoryPageNum=flag;
flag++;
p[0].pageOffset=12;
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;mif(p[m].pageOffset!
=-1)
printf("%8d%8d%8d%8d%11d\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
else
printf("%8d%8d%8d%8d----\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset);
printf("请输入要调用的虚页号和页内偏移(中间用空格隔开):
");
scanf("%d%d",&taskpage,&task_offset);
//当用户输入的虚页数大于预设退出程序
while(taskpage{
//当内存有空余的块直接装入
//未命中的情况下将调入的页号装入内存
for(inti=0;iif(taskpage==i)
//未命中的情况
if(p[i].isMemory==0)
{
//内存还有空余memoryBlockNum是从输入的数值往下减
if(memoryBlockNum>1)
{
p[i].isMemory=1;
p[i].pageOffset=task_offset;
p[i].memoryPageNum=flag%memory_block,
flag++;
memoryBlockNum--;
//printf("虚页调入内存中的物理地址为:
%d\n",p[i].memoryPageNum*page_size+base_address+p[i].pageOffset);
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;m//显示调入
if(p[m].pageOffset!
=-1)
{
if(i==m)
printf("%8d%8d%8d%8d%11d调入\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
else
printf("%8d%8d%8d%8d%11d\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
}
else
printf("%8d%8d%8d%8d----\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset);
}else
{
//内存已用完且未命中
//flag%memory_block目前的值为即将装入的内存块号
for(intj=0;j{
if(p[j].memoryPageNum==flag%memory_block)
{
mid_temp=j;
}
}
//将要替换出内存的页号状态进行修改
p[mid_temp].memoryPageNum=-1;
p[mid_temp].isMemory=0;
p[mid_temp].pageOffset=-1;
//将即将调入的页号状态进行修改
p[i].isMemory=1;
p[i].pageOffset=task_offset;
p[i].memoryPageNum=flag%memory_block;
flag++;
memoryBlockNum--;
//printf("虚页调入内存中的物理地址为:
%d\n",p[i].memoryPageNum*page_size+base_address+p[i].pageOffset);
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;m//显示调入
if(p[m].pageOffset!
=-1)
{
if(i==m)
printf("%8d%8d%8d%8d%11d调入\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
else
printf("%8d%8d%8d%8d%11d\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
}
else
printf("%8d%8d%8d%8d----\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset);
}
}
else
//在内存命中情况
{
//更新偏移地址
p[i].pageOffset=task_offset;
//printf("命中页号在内存中的物理地址为:
%d\n",p[i].memoryPageNum*page_size+base_address+p[i].pageOffset);
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;m//显示命中
if(p[m].pageOffset!
=-1)
{
if(i==m)
printf("%8d%8d%8d%8d%11d命中\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
else
printf("%8d%8d%8d%8d%11d\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
}
else
printf("%8d%8d%8d%8d----\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset);
}
printf("请输入要调用的虚页号和页内偏移(中间用空格隔开):
");
scanf("%d%d",&taskpage,&task_offset);
}
}
voidLRU()
{
intflag=0;
//用于记录数组中的角码
intmid_temp;
//进程的页数
inttaskNum;
//用户输入的虚页号
inttaskpage;
//内存分的块数定值会被改变
intmemoryBlockNum;
inttask_offset;
//内存分的块数定值不会变
intmemory_block;
printf("请输入虚页总数:
\n");
scanf("%d",&taskNum);
printf("请输入内存块数目:
\n");
scanf("%d",&memoryBlockNum);
memory_block=memoryBlockNum;
//动态定义数组
page*p=(page*)malloc(taskNum*sizeof(page));
//对结构体初始化
for(inti=0;ip[i].taskPageNum=i,
p[i].isMemory=0,
p[i].memoryPageNum=-1,
p[i].pageOffset=-1,
p[i].info=-1;
//首先装入0号页
p[0].isMemory=1;
p[0].memoryPageNum=flag;
flag++;
p[0].pageOffset=12;
p[0].info=memory_block-1;
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;mif(p[m].pageOffset!
=-1)
printf("%8d%8d%8d%8d%11d\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
else
printf("%8d%8d%8d%8d----\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset);
printf("请输入要调用的虚页号和页内偏移(中间用空格隔开):
");
scanf("%d%d",&taskpage,&task_offset);
////////////////////////////////////////////////////
while(taskpage{
//当内存有空余的块直接装入
//未命中的情况下将调入的页号装入内存
for(inti=0;iif(taskpage==i)
//未命中的情况
if(p[i].isMemory==0)
{
//内存还有空余memoryBlockNum是从输入的数值往下减
if(memoryBlockNum>1)
{
p[i].isMemory=1;
p[i].pageOffset=task_offset;
p[i].memoryPageNum=flag%memory_block,
p[i].info=memory_block;
flag++;
memoryBlockNum--;
//将所有info》0的数值减一
for(m=0;mif(p[m].info>-1)
p[m].info=p[m].info-1;
//printf("虚页调入内存中的物理地址为:
%d\n",p[i].memoryPageNum*page_size+base_address+p[i].pageOffset);
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;m//显示调入
if(p[m].pageOffset!
=-1)
{
if(i==m)
printf("%8d%8d%8d%8d%11d调入\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
else
printf("%8d%8d%8d%8d%11d\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
}
else
printf("%8d%8d%8d%8d----\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset);
}else
{
//以下核心算法修改处
//内存已用完且未命中
//p[j]目前的值为即将装入的内存块号
inttemporary=99999;
for(intj=0;j{
if(p[j].info>-1&&temporary>p[j].info)
temporary=p[j].info,
mid_temp=j;
}
//核心算法修改处结束
//将要替换出内存的页号状态进行修改
p[mid_temp].memoryPageNum=-1;
p[mid_temp].isMemory=0;
p[mid_temp].pageOffset=-1;
p[mid_temp].info=-1;
//将即将调入的页号状态进行修改
p[i].isMemory=1;
p[i].pageOffset=task_offset;
p[i].memoryPageNum=flag%memory_block;
flag++;
p[i].info=memory_block;
memoryBlockNum--;
//将所有info》0的数值减一
for(m=0;mif(p[m].info>-1)
p[m].info=p[m].info-1;
//printf("虚页调入内存中的物理地址为:
%d\n",p[i].memoryPageNum*page_size+base_address+p[i].pageOffset);
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;m//显示调入
if(p[m].pageOffset!
=-1)
{
if(i==m)
printf("%8d%8d%8d%8d%11d调入\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
else
printf("%8d%8d%8d%8d%11d\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset,p[m].memoryPageNum*page_size+base_address+p[m].pageOffset);
}
else
printf("%8d%8d%8d%8d----\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].isMemory,p[m].pageOffset);
}
}
else
//在内存命中情况
{
//更新偏移地址
p[i].pageOffset=task_offset;
p[i].info=memory_block;
//将所有info》0的数值减一
for(m=0;mif(p[m].info>-1)
p[m].info=p[m].info-1;
//printf("命中页号在内存中的物理地址为:
%d\n",p[i].memoryPageNum*page_size+base_address+p[i].pageOffset);
//输出页表装入情况
printf("虚页号内存块号装入位页内偏移物理地址\n");
for(intm=0;m//显示调入
if(p[m].pageOffset!
=-1)
{
if(i==m)
printf("%8d%8d%8d%8d%11d命中\n",p[m].taskPageNum,p[m].memoryPageNum,p[m].