虚拟存储器管理实验报告.doc

上传人:wj 文档编号:2142185 上传时间:2023-05-02 格式:DOC 页数:10 大小:78.50KB
下载 相关 举报
虚拟存储器管理实验报告.doc_第1页
第1页 / 共10页
虚拟存储器管理实验报告.doc_第2页
第2页 / 共10页
虚拟存储器管理实验报告.doc_第3页
第3页 / 共10页
虚拟存储器管理实验报告.doc_第4页
第4页 / 共10页
虚拟存储器管理实验报告.doc_第5页
第5页 / 共10页
虚拟存储器管理实验报告.doc_第6页
第6页 / 共10页
虚拟存储器管理实验报告.doc_第7页
第7页 / 共10页
虚拟存储器管理实验报告.doc_第8页
第8页 / 共10页
虚拟存储器管理实验报告.doc_第9页
第9页 / 共10页
虚拟存储器管理实验报告.doc_第10页
第10页 / 共10页
亲,该文档总共10页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

虚拟存储器管理实验报告.doc

《虚拟存储器管理实验报告.doc》由会员分享,可在线阅读,更多相关《虚拟存储器管理实验报告.doc(10页珍藏版)》请在冰点文库上搜索。

虚拟存储器管理实验报告.doc

防灾科技学院实验报告

系别

灾害信息工程系

专业班级

0950412

学号

095041219

学生姓名

郑平贞

实验日期

2011-12-8

成绩

课程名称

计算机操作系统

实验题目

虚拟存储器管理

实验记录

实验目的:

1理解虚拟存储器的概念

2掌握分页式存储管理地址转换和缺页中断

实验环境:

WindowsXPVC++6.0

实验内容:

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

2用先进先出页面调度算法处理缺页中断

实验过程:

1.实验设计

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

分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业被选中时,可把作业的开始几页先装入主存且启动执行。

为此,在为作业建立页表时,应说明哪些页已在主存,哪些页尚未装入主存。

作业执行时,指令中的逻辑地址指出了参加运算的操作存放的页

号和单元号,硬件的地址转换机构按页号查页表,若该页对应标志为“1”,则表示该页已在主存,这时根据关系式“绝对地址=块号×块长+单元号”计算出欲访问的主存单元地址。

如果块长为2的幂次,则可把块号作为高地址部分,把单元号作为低地址部分,两者拼接而

成绝对地址。

若访问的页对应标志为“0”,则表示该页不在主存,这时硬件发“缺页中断”信号,有操作系统按该页在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。

设计一个“地址转换”程序来模拟硬件的地址转换工作。

当访问的页在主存时,则

形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指令的执行。

当访问的页不在主存时,则输出“*该页页号”,表示产生了一次缺页中断。

(2)用先进先出(FIFO)页面调度算法处理缺页中断。

FIFO页面调度算法总是淘汰该作业中最先进入主存的那一页,因此可以用一个数组来表示该作业已在主存的页面。

假定作业被选中时,把开始的m个页面装入主存,则数组的元素可定为m个。

2.程序代码:

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

#include

#include

#defineSizeOfPage100

#defineSizeOfBlock128

#defineM4

structinfo//页表

{

boolflag;//标志

longblock;//块号

longdisk;//在磁盘上的位置

booldirty;//修改标志

}pagelist[SizeOfPage];

longpo;//队列标记

longP[M];

voidinit_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;

}

voidwork_ex1()

{

boolstop=0;

longp,q;

chars[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);

}

voidinit_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;

}

voidwork_ex2()

{

longp,q,i;

chars[100];

boolstop=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

{

printf("P[%ld]=%ld\n",i,P[i]);

}

}

voidselect()

{

longse;

chars[128];

do

{

printf("请选择题号(1/2):

");

if(scanf("%ld",&se)!

=1)

{

scanf("%s",s);

if(strcmp(s,"exit")==0)

{

return;

}

}

else

{

if(se==1)

{

init_ex1();

work_ex1();

}

if(se==2)

{

init_ex2();

work_ex2();

}

}

}while

(1);

}

intmain()

{

select();

return0;

}

(2)用先进先出(FIFO)页面调度算法处理缺页中断。

#include

#include

#include//页表用数组模拟,在实验中页表数据结构定义为:

#defineN32//实验中假定的页表长度,页表的长度实际上是由系统按照作业长度决定的

#defineM4//实验中用,用固定局部置换算法给每个进程分配的主存物理块数

struct

{intlnumber;//页号

intflag;//表示该页是否在主存,"1"表示在主存,"0"表示不在主存

intpnumber;//该页所在主存块的块号

intwrite;//该页是否被修改过,"1"表示修改过,"0"表示没有修改过

intdnumber;//该页存放在磁盘上的位置,即磁盘块号

}page[N];//页表定义

intp[M];//用数组模拟]FIFO算法中的队列(使用循环队列)

inthead;

voidinitial(void);//初始化

intdo_mmap(int);//模拟地址转换

voiddo_page_fault(int);//缺页中断处理程序

voidrun_first_instructon(int);//执行进程的第一条指令

voidrun_a_instruction(int);//CPU执行一条指令

voidprint_page_and_fifoqueue(void);//输出页表和FIFO队列

main()

{

intladdress,paddress;//逻辑地址,物理地址

intlnumber,ad,pnumber;//页号,页内地址和物理块号

initial();//手工初始化页表

print_page_and_fifoqueue();//输出页表和FIFO队列

run_first_instructon(0x0000);//运行进程的第一条指令的地址

//输入下一条指令的地址

cout<<"输入下一条指令的逻辑地址(0~32767)(-1toend)"<

cin>>laddress;

while(laddress>32767){//输入正确性检测

cout<<"EnterERORR!

请重新输入下一条指令的逻辑地址(0~32767)(-1toend)"<

cin>>laddress;

}

while(laddress!

=-1){//还有指令要执行

lnumber=laddress>>10;//取逻辑地址的页号lnumber

if(page[lnumber].flag==1){//指令所在的页面已装入在内存中

paddress=do_mmap(laddress);//形成物理地址

cout<

run_a_instruction(paddress);//CPU根据得到的物理地址去执行指令

cout<<"此指令执行是否修改所在页面lnumber="<

)";

charchange;

cin>>change;

if(tolower(change)=='y'){

page[lnumber].write=1;//若页面要已修改,则将此页面修改位置1

print_page_and_fifoqueue();

}

}

else{//缺页中断

cout<

do_page_fault(lnumber);//直接转去缺页中断处理

continue;//本循环结束,重新执行指令

}

cout<<"输入下一条指令的逻辑地址((0~32767)),-1toend.\n";

cin>>laddress;

while(laddress>32767){//输入正确性检测

cout<<"EnterERORR!

请重新输入下一条指令的逻辑地址(0~32767)(-1toend)"<

cin>>laddress;

}

}

cout<<"祝贺,进程运行结束!

"<

system("PAUSE");

return0;

}

//手工初始化页表和p[M]队列

voidinitial(void)

{

inti;

for(i=0;i=31;i++){

page[i].lnumber=i;

if(i=M-1){//预装入算法初始化页表的前四项

cout<<"输入页号为"<

";

cin>>page[i].pnumber;

page[i].flag=1;//存在标志置1

}

}

//初始化FIFO的队列

head=0;

for(i=0;i=M-1;i++)

p[i]=i;

}

//输出页表和FIFO队列

voidprint_page_and_fifoqueue(void)

{

inti;

cout<<"Printthepagetable.\n";

cout<

<

for(i=0;i=N-1;i++)

cout<

<

cout<<"PrinttheFIFOqueue.\n";

cout<

cout<<"head="<

for(i=0;i=M-1;i++)

cout<

}//模拟地址转换

intdo_mmap(intladdress)

{

intlnumber,ad,pnumber,paddress;

lnumber=laddress>>10;//取逻辑地址的页号lnumber

ad=laddress&0x3ff;//页内地址

pnumber=page[lnumber].pnumber;//从页表中取得块号pnumber

paddress=pnumber<<10|ad;

returnpaddress;

}//CPU执行一条指令,输出物理地址表示指令执行完成

voidrun_a_instruction(intpaddress)

{

cout<

}//执行进程的第一条指令

voidrun_first_instructon(intladdress)

{

intlnumber,ad,pnumber,paddress;

lnumber=laddress>>10;//取逻辑地址的页号

if(page[lnumber].flag==1)//由于式预装入方式,所以第一条指令所在的页面肯定在内存中

paddress=do_mmap(laddress);//形成物理地址

cout<

run_a_instruction(paddress);

cout<<"此指令执行(0x0000)是否修改所在页面lnumber="<

)";

charchange;

cin>>change;

if(tolower(change)=='y'){//若指令执行完时修改了页面,则置write标志位位1

page[lnumber].write=1;

print_page_and_fifoqueue();

}

cout<<"********第一条指令执行完成(地址为0x0000)***********"<

}

//页面写回磁盘

voidwrite_to_harddisk(intj)

{

cout<

}

//缺页中断处理程序

voiddo_page_fault(intlnumber)

{

intj;//j是选择淘汰的页

j=p[head];

p[head]=lnumber;//lnumber是新装入的页号

head=(head+1)%M;

//若淘汰出主存的页j已修改,则写会磁盘

if(page[j].write==1)

write_to_harddisk(j);//页j写回磁盘

//修改页表

page[j].flag=0;//页表中第j页的存在标志为0

page[lnumber].flag=1;//页表第lnumber的存在标志为1

page[lnumber].write=0;//页表第lnumber的修改标志为0

page[lnumber].pnumber=page[j].pnumber;//第拉怒目布尔页的主存块号为第j页原主存块号

cout<

cout<<"按任意键将查看“页面置换”之后的页表page[N]和FIFO队列信息"<

system("PAUSE");

print_page_and_fifoqueue();

}

3.实验结果

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

输入要分配的物理块数、页面总数、页面序列号

(2)FIFO算法的实现

FIFO算法的实现

4.实验分析

 系统的不足包括健壮性尚不够好,界面比较简单,对页表的初始化需要修改程序。

   经验体会:

注意体会算法的精神,程序前后逻辑要一致。

注意测试时数据的全面性。

实验总结:

编程不用太复杂,实用就行。

实验地点

机房305

指导教师

陈新房

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2