模拟动态分区存储管理中地址转换.docx
《模拟动态分区存储管理中地址转换.docx》由会员分享,可在线阅读,更多相关《模拟动态分区存储管理中地址转换.docx(13页珍藏版)》请在冰豆网上搜索。
模拟动态分区存储管理中地址转换
模拟动态分区存储管理中地址转换
1.实验目的
深入了解动态分区存储管理方式的内存分配以及地址转换的实现。
2.实验任务
随机产生进程的个数及需要的空间,当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后有关地址转换的数据。
3.系统功能需求分析
系统对内存的管理和控制通过数据结构——分区说明表进行,分区说明表说明各分区号、分区大小、起始地址和是否是空闲区(分区状态)。
内存的分配释放、存储保护以及地址变换等都通过分区说明表进行。
地址映射:
把程序中的相对地址(或逻辑地址)转换为内存中的绝对地址(物理地址)。
动态分区的基本思想:
在作业执行前并不直接建立分区,分区的建立是在作业的处理过程中进行的,且其大小可随作业或进程对内存的要求而改变。
在系统初启时,除了操作系统中常驻内存部分之外,只有一个空闲分区。
随后,分配程序将该区依次划分给调度选种的作业或进程。
随着进程的执行,会出现一系列的分配和释放。
比如在某一时刻,一进程执行结束并释放内存之后,管理程序又要为另两个进程分配内存。
如果分配的空闲区比所要求的大,则管理程序将该空闲区分为两个部分,其中一部分成为已分配区而另一部分成为一个新的小空闲区
动态地址重定位:
是在程序执行过程中,在CPU访问内存之前,将要访问的程序或数据地址转换成内存地址。
地址重定位机构需要一个(或多个)基地址寄存器BR和一个(或多个)程序虚拟地址寄存器VR。
指令或数据的内存地址MA与虚拟内存的关系为MA=(BR)+(VR)。
地址转换的原因:
当程序从外存进入内存时,原来的相对地址已经不能反映程序在内存中的实际地址了,因为程序在装入内存的过程中,它的装入地址不是由程序来选择的,而是由当前可用内存的实际情况来决定的,所以说,用程序地址编写的程序一旦送入内存,其程序地址和内存物理地址之间就存在一种对应关系。
为使程序正常运行,需要将这种对应关系实施地址变换。
动态创建分区:
在装入程序和其执行过程中通过系统调用时都进行随机分配内存大小。
程序的名字空间、地址空间和存储空间之间的关系:
汇编编译连接
名字空间地址空间
地址重定位
存储空间
4.开发平台
系统:
Windowsxp环境
开发工具:
VC
编程语言:
C++
5.系统的功能设计
内存初始分配情况:
voidinit()//链表初始化,只有一个节点
{
head=newtable;
head->start=1;
head->length=memory;
head->state=false;
head->next=NULL;
}
boolfenpei(table*p)//分配进程
动态重定位过程:
1设置基地址寄存器BR,虚拟地址寄存器VR。
2将程序段装入内存,且将其站用的内存区首地址送BR中。
3在程序段执行过程中,将所要访问的虚拟地址送入VR中。
4地址变换机构把VR和BR的内容相加,得到实际访问的物理地址。
1
0BR2
3
1VR4
5
46
7
虚拟空间内存空间
动态分区时采用最先适应算法:
该算法要求可用表或自由链按起始地址递增的次序排列,从所找到的分区中化出所要求的内存长度分配给用户,并把余下的部分进行合并(如有相邻空闲区存在)后留在可用表中,但要修改其相应的表项。
如图:
数据结构定义:
#defineN10//最大进程数
#definema10//每个进程的最大容量
#definememory100//整个内存大小
structtable{//已分配的或未分配的
intstart;//进程起始地址
intlength;//进程大小
boolstate;//是否分配false:
未分配true:
已分配
table*next;
};
intn;//实际的进程数
intbr;
intvr;
table*head;//head
intrandom(inta,intb)//产生随机数从a到b
{
unsignedintseedVal;
structtimebtimeBuf;
ftime(&timeBuf);
seedVal=((((unsignedint)timeBuf.time&0xFFFF)+
(unsignedint)timeBuf.millitm)^
(unsignedint)timeBuf.millitm);
srand((unsignedint)seedVal);
intx=a+rand()%b-a+1;
Sleep(10);
returnx;
}
voidfangwen(intbr,intvr)//模拟访问内存
{
cout<<"正在访问内存中.";
Sleep(800);
cout<<".";
Sleep(800);
cout<<".";
Sleep(800);
cout<}
for(intindex=0;index!
=N;++index)
{
br=random(1,N);
vr=random(1,ma);
cout<<"用户程序正试图访问第"<
for(inti=1;i!
=n+1;++i)
{
table*t=newtable;
t->length=random(1,ma);
if(fenpei(t))
{
cout<<"内存分配成功!
"<}
else
cout<<"内存分配失败!
"<}
6.运行结果与运行情况分析
由于产生的最大进程数为5,不存在第6个进程数,因此在访问第6个进程时,发生BR越界。
由于第5个进程被分配的内存为3个单元,因此不存在第5个单元,在访问该进程的第5个单元时发生VR越界。
由于产生的最大进程数为3,不存在第8个进程数,因此在访问第6个进程时,发生BR越界。
7.自我评价与总结
通过这次实验我深刻理解到,动态分区分配是根据进程的实际需要动态的为之分配内存空间,在实现可变分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配操作这样三个问题。
而地址转换也就是地址重定位包括静态重定位和动态重定位。
内存地址的集合称为内存空间或物理空间。
内存中,每一个存储单元都与相应的成为内存地址的编号相对应。
而把虚拟空间中已经链接和划分好的内容装如内存,并将虚拟地址映射为内存地址的问题就称之为重定位或地址映射。
虽然上述的这些概念通过课本以及课堂上老师的讲解早已知道,但这“知道”并不是弄懂并理解透彻了,而通过这次实验才真正有了深刻的体会。
本次实验我认为程序的运行结果很清楚明了的反映了随机产生进程以及内存分配的过程以及BR和VR越界的处理。
然而由于我前面对面有关方面的知识掌握不够牢固以及C对++编程语言学习和实际运用的匮乏,此次的实验并没有预期的完美。
首先,我本打算把每个进程进程编号,但考虑后续操作的复杂也就没有实施;再次,此次实验要求显示为该进程分配资源后有关地址转换的数据,我也没能够做到;最后我也漏掉了对内存进行回收。
由于浪费很多的时间在此次实验的代码编写过程中,所以也没能够想出其他的方法完成此次实验。
8.参考文献
1、《计算机操作系统教程》第2版张尧学史美林编著清华大学出版社
2、《操作系统学习辅导》张献忠主编清华大学出版社
3、《操作系统教程——原理和实例分析》孟静高等教育出版社