实验三存储管理实验Word文件下载.docx
《实验三存储管理实验Word文件下载.docx》由会员分享,可在线阅读,更多相关《实验三存储管理实验Word文件下载.docx(25页珍藏版)》请在冰豆网上搜索。
typedefstructpartiTabPARTITAB;
typedefstructjcb
charname[10];
structjcb*link;
}JCB;
typedefstruct
JCB*front,*rear;
}jcbQue;
jcbQue*jcbReadyQue;
voidAllocateMemory(intsize);
voidcreateTab();
voidcheckTab();
voidrecycleMemory(inti);
voidAllocateMemory(intsize)
inti;
intn=0;
for(i=0;
i<
NUM;
i++)
{
PARTITABp=parTab[i];
if(p.state=='
N'
&
&
p.size>
size)
parTab[i].state='
Y'
;
n=1;
break;
}
if(n==0)
printf("
内存大小是%d\t"
size);
无法分配内存!
\n"
);
else
装入内存成功!
}
voidcreateTab()
parTab[0].no=0;
parTab[0].size=12;
parTab[0].firstAddr=20;
parTab[0].state='
parTab[1].no=1;
parTab[1].size=32;
parTab[1].firstAddr=32;
parTab[1].state='
parTab[2].no=2;
parTab[2].size=64;
parTab[2].firstAddr=64;
parTab[2].state='
parTab[3].no=3;
parTab[3].size=128;
parTab[3].firstAddr=128;
parTab[3].state='
voidcheckTab()
分区号\t大小\t起址\t状态\n"
%d\t"
parTab[i].no);
parTab[i].size);
parTab[i].firstAddr);
%c\t"
parTab[i].state);
voidrecycleMemory(inti)
parTab[i-1].state='
intmain(intargc,char*argv[])
intk=1+rand()%100;
****固定式分区分配存储管理******\n"
createTab();
checkTab();
请按任意键继续:
getchar();
一次装入多个作业:
AllocateMemory(k);
k=1+rand()%100;
若继续装入作业\n"
若有一个作业完成\n"
k=rand()%4;
recycleMemory
(2);
继续装入作业\n"
return0;
截图显示为:
2、设计一个可变式分区分配的存储管理方案。
并模拟实现分区的分配和回收过程。
对分区的管理法可以是下面三种算法之一:
首次适应算法
循环首次适应算法
最佳适应算法
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;
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;
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<
s++;
if(s>
找不到该作业\n"
used_table[s].flag=0;
S=used_table[s].address;
L=used_table[s].length;
j=-1;
k=-1;
i=0;
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!
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;
free_table[j].address=S;
free_table[j].length=free_table[j].length+L;
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()
inti,a,b=4;
floatxk;
charJ;
free_table[0].address=10240;
free_table[0].length=10240;
free_table[0].flag=1;
for(i=1;
free_table[i].flag=0;
n;
used_table[i].flag=0;
while(b==4)
请选择功能项:
0、退出!
1、分配主存!
2、回收主存!
3、显示主存!
\n"
选择功项(0~3):
scanf("
%d"
&
a);
switch(a)
case0:
exit(0);
case1:
输入作业名作业所需长度:
"
%*c%c%f"
J,&
xk);
allocate(J,xk);
case2:
输入要回收分区的作业名"
%*c%c"
J);
reclaim(J);
case3:
输出空闲区表:
\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:
printf("
没有该选项\n"
截图得:
3、编写并调试一个段页式存储管理的地址转换的模拟程序。
首先设计好段表、页表,然后给出若干个有一定代表性的地址,通过查找段表页表后得到转换的地址。
要求打印转换前的地址,相应的段表,页表条款及转换后的地址,以便检查。
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();
voidmenu()
cout<
<
"
段页式存储管理的地址转换的模拟程序"
endl;
请选择相应的序号:
1、初始化表"
2、物理地址转换"
3、退出"
intmenu1;
cin>
>
menu1;
if(menu1!
=1&
menu1!
=2&
=3)
请输入正确的选项"
menu();
switch(menu1)
menuflag=1;
start();
if(menuflag==0)
请初始化表"
change();
}//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].num>
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()
请输入要转化的逻辑地址,段号,段内页号,页内偏移地址"
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<
快表没有命中,访问段表寄存器"
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+dnum<
此时将此项内容添加到快表里面"
intmain()
截图可以得到:
四.实验总结
这次的实验对于我来说还是比较难的,几乎每次都是这样,看书的时候能够理解书上的讲解,也大概了解存储管理的过程和原理,但是在编写代码的时候却总是一团迷雾,不知道从哪里下手才好,我从网上找了代码,然后阅读理解了,但是代码里面有很多错误,而且有的过程也是错的,我就改正了一下。
就比如说第一题来说,网上代码是将分区说明表是采取循环的方式进行设置,但是我觉得不太好,所以就以四个为例逐个的进行设置,虽然比较麻烦而且代码比较冗余,但是这样可以设置不同大小的固定