《操作系统》存储管理实验报告Word格式文档下载.docx
《《操作系统》存储管理实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《《操作系统》存储管理实验报告Word格式文档下载.docx(23页珍藏版)》请在冰豆网上搜索。
charname[10];
//作业名
//作业大小
structjcb*link;
//链指针
}JCB;
typedefstruct
JCB*front,*rear;
}jcbQue;
jcbQue*jcbReadyQue;
voidAllocateMemory(intsize);
voidcreateTab();
voidcheckTab();
voidrecycleMemory(inti);
voidAllocateMemory(intsize)
inti;
for(i=0;
i<
NUM;
i++)
PARTITABp=parTab[i];
if(p.state='
N'
&
&
p.size>
size)
parTab[i].state='
Y'
;
else
printf("
没有空闲分区,无法分配内存!
\n"
);
}
voidcreateTab()
inti;
for(i=1;
=NUM;
//getPartiTab(PARTITAB);
parTab[i-1].no=i;
parTab[i-1].size=20;
parTab[i-1].firstAddr=21;
parTab[i-1].state='
voidcheckTab()
printf("
分区号\t大小\t起址\t状态\n"
%d\t"
parTab[i].no);
parTab[i].size);
parTab[i].firstAddr);
%c\t"
parTab[i].state);
voidrecycleMemory(inti)
intmain(intargc,char*argv[])
\n\n\t\t*********************************************\t\t\n"
\t\t\t\t实验一存储管理实验\n"
\t\t\t\t固定式分区分配存储管理\n"
\t\t*********************************************\t\t\n"
createTab();
checkTab();
请按任意键继续:
getchar();
每个分区装入一道作业:
i++){
AllocateMemory((i+1)*3);
假如一段时间后,其中一个作业结束,回收给它分配的分区(假如该作业在第2分区)\n"
recycleMemory
(2);
接着,从外存后备作业队列中选择一个作业装入该分区(假如该作业大小为10)\n"
AllocateMemory(10);
return0;
dos.h>
conio.h>
#definen10
#definem10
#defineminisize100
struct
floataddress;
floatlength;
intflag;
}used_table[n];
}free_table[m];
voidallocate(charJ,floatxk)
inti,k;
floatad;
k=-1;
i<
m;
i++)
if(free_table[i].length>
=xk&
free_table[i].flag==1)
if(k==-1||free_table[i].length<
free_table[k].length)
k=i;
if(k==-1)
无可用空闲区\n"
return;
if(free_table[k].length-xk<
=minisize)
free_table[k].flag=0;
ad=free_table[k].address;
xk=free_table[k].length;
else{
free_table[k].length=free_table[k].length-xk;
ad=free_table[k].address+free_table[k].length;
i=0;
while(used_table[i].flag!
=0&
n)
i++;
if(i>
=n)
无表目填写已分分区,错误\n"
if(free_table[k].flag==0)
free_table[k].flag=1;
else
free_table[k].length=free_table[k].length+xk;
used_table[i].address=ad;
used_table[i].length=xk;
used_table[i].flag=J;
voidreclaim(charJ)
inti,k,j,s,t;
floatS,L;
s=0;
while((used_table[s].flag!
=J||used_table[s].flag==0)&
s<
n)
s++;
if(s>
找不到该作业\n"
used_table[s].flag=0;
S=used_table[s].address;
L=used_table[s].length;
j=-1;
while(i<
m&
(j==-1||k==-1))
if(free_table[i].flag==1)
if(free_table[i].address+free_table[i].length==S)k=i;
if(free_table[i].address==S+L)j=i;
if(k!
=-1)
if(j!
=-1)/*上邻空闲区,下邻空闲区,三项合并*/
free_table[k].length=free_table[j].length+free_table[k].length+L;
free_table[j].flag=0;
/*上邻空闲区,下邻非空闲区,与上邻合并*/
free_table[k].length=free_table[k].length+L;
elseif(j!
=-1)/*上邻非空闲区,下邻为空闲区,与下邻合并*/
free_table[j].address=S;
free_table[j].length=free_table[j].length+L;
else/*上下邻均为非空闲区,回收区域直接填入*/
/*在空闲区表中寻找空栏目*/
t=0;
while(free_table[t].flag==1&
t<
m)
t++;
if(t>
=m)/*空闲区表满,回收空间失败,将已分配表复原*/
主存空闲表没有空间,回收空间失败\n"
used_table[s].flag=J;
free_table[t].address=S;
free_table[t].length=L;
free_table[t].flag=1;
}/*主存回收函数结束*/
intmain()
\t\t\t\t实验三存储管理实验\n"
\n\t\t\t可变式分区分配(最佳适应算法)\n"
\t\t*********************************************\n"
inti,a;
floatxk;
charJ;
/*空闲分区表初始化:
*/
free_table[0].address=10240;
/*起始地址假定为10240*/
free_table[0].length=10240;
/*长度假定为10240,即10k*/
free_table[0].flag=1;
/*初始空闲区为一个整体空闲区*/
for(i=1;
free_table[i].flag=0;
/*其余空闲分区表项未被使用*/
/*已分配表初始化:
n;
used_table[i].flag=0;
/*初始时均未分配*/
while
(1)
功能选择项:
\n1。
显示主存\n2。
分配主存\n3。
回收主存\n4。
退出\n"
请选择相应功能1--4:
"
scanf("
%d"
&
a);
switch(a)
case4:
exit(0);
/*a=4程序结束*/
case2:
/*a=2分配主存空间*/
输入作业名J和作业所需空间xk:
"
%*c%c%f"
J,&
xk);
allocate(J,xk);
/*分配主存空间*/
break;
case3:
/*a=3回收主存空间*/
输入要回收分区的作业名"
%*c%c"
J);
reclaim(J);
/*回收主存空间*/
case1:
/*a=1显示主存情况*/
/*输出空闲区表和已分配表的内容*/
输出空闲区表:
\n起始地址分区长度标志\n"
%6.0f%9.0f%6d\n"
free_table[i].address,free_table[i].length,free_table[i].flag);
按任意键,输出已分配区表\n"
getch();
输出已分配区表:
if(used_table[i].flag!
=0)
%6.0f%9.0f%6c\n"
used_table[i].address,used_table[i].length,used_table[i].flag);
default:
没有该选项\n"
}/*case*/
}/*while*/
return1;
iostream>
string>
usingnamespacestd;
typedefstructQuick
intqs;
//快表段号
intqp;
//快表页号
intqb;
}Quick;
typedefstructData
intnum;
//内存的块数
stringstr;
//对应数据块的作业内容,简化起见说明内容为一串字符。
}Data;
//页表
typedefstructPage
//页号
intflag;
//页状态,即是否在内存。
intblock;
//该页对应的块号
}Page;
typedefstructStack
//段号
//段状态
intplen;
//页表长度
intpsta;
//页表始址
}Stack;
//段表寄存器
typedefstructStare
intssta;
//段表始址
intslen;
//段表长度
}Stare;
Stackss[10];
////全局变量
Starest;
///////全局变量
Datawork[20];
//全局变量
Quickqu;
//////全局变量
Pagepage[5][5];
boolmenuflag=0;
intbbs;
//内存块大小
intbs;
//内存大小
voidmenu();
voidstart();
voidchange();
intmain()
menu();
return0;
voidmenu()
{cout<
<
\n\n\t\t*********************************************\t\t"
endl;
cout<
\t\t\t\t实验三存储管理实验"
\n\t\t\t段页式存储管理的地址转换的模拟程序"
\t\t*********************************************"
请选择:
1、初始化表"
2、物理地址转换"
3、退出"
intmenu1;
cin>
>
menu1;
if(menu1!
=1&
menu1!
=2&
=3)
{
请输入正确的选项"
}
switch(menu1)
case1:
menuflag=1;
start();
break;
case2:
if(menuflag==0)
请初始化表"
change();
case3:
return;
}//switch
voidstart()
请输入内存大小(K)"
bs;
请输入内存块的大小(k)"
bbs;
intblocknum;
blocknum=bs/bbs;
内存一共被分为"
blocknum<
块,每块"
bbs<
k"
一共"
bs<
请输入进程个数"
intpn;
pn;
//下面求所有进程的总段数和段表,并为每段创建页表
intsums=0;
for(intpn1=0;
pn1<
pn1++)
请输入第"
pn1<
个进程的段数"
intppn;
ppn;
sums+=ppn;
for(intss1=0;
ss1<
sums;
ss1++)
ss1<
个段表数据:
段号,状态,页表长度,页表始址"
ss[ss1].num>
ss[ss1].flag>
ss[ss1].plen>
ss[ss1].psta;
请初始化第"
段的页表,输入两个数据页表状态和对应块号"
for(intsss1=0;
sss1<
ss[ss1].plen;
sss1++)
page[ss1][sss1].num=sss1;
请输入该段第"
sss1<
个页表的页表状态和对应块号"
page[ss1][sss1].flag>
page[ss1][sss1].block;
//初始化段表寄存器
初始化段表寄存器的段表始址"
st.ssta;
st.slen=sums;
//初始化内存中物理地址每一块的数据区
简单起见,我们对物理地址的每一块用字符串进行简单的初始化,没有具体到每一物理地址"
for(intbn=0;
bn<
blocknum;
bn++)
work[bn].num=bn;
bn<
个内存块里的作业内容"
work[bn].str;
//初始化快表
简单起见,我们初始化快表只有一个"
请输入要作为快表的段号和页号"
qu.qb>
qu.qp;
while(ss[qu.qb].flag!
=1||page[qu.qb][qu.qp].flag!
=1)
该页不在内存请输入一页在内存中的作为快表,请输入要作为快表的段号和页号"
qu.qs=page[qu.qb][qu.qp].block;
voidchange()
请输入要转化的逻辑地址,段号s,段内页号p,页内偏移地址d(B)"
intsnum,pnum,dnum;
snum>
pnum>
dnum;
//首先查快表
if(snum==qu.qb&
pnum==qu.qp)
快表命中"
对应块号是"
qu.qs<
该块中作业数据是"
work[page[qu.qb][qu.qp].block].str<
物理地址是"
qu.qs*bbs*1024+dnum<
//访问段表寄存器
else
快表没有命中,访问段表寄存器,段号等于段表始址加上偏移地址"
intssnum;
ssnum=st.ssta+snum;
if(ssnum>
st.slen-1)
越界中断"
//访问段表
ssnum<
=st.slen-1)
//是否缺段
段表有效"
if(ss[ssnum].flag==0)
缺段中断"
//查询页表,根据段号查出页表始址,加上段内偏移页数,即得到页表项。
//缺页中断测试
if(pnum>
ss[ssnum].plen-1)
缺页中断"
pnum<
=ss[ssnum].plen-1)
if(page[ssnum][pnum].flag==0)
找到该页"
查询页表后对应块号"
page[ssnum][pnum].block<
该块内存的数据是"
work[page[ssnum][pnum].block].str<
转化得到的物理地址是:
page[ssnum][pnum].block*bbs*1024+dn