模拟设计段页式虚存储
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
int block;
};
struct Segment
{
Page Pages[100];
int Pnum;
};
struct Process
//进程结构体的定义
{
Segment Segments[10];
int isInMem;
int Snum;
int Total;
};
Process Procs[ProTableSize];
Procs[i].Total=0; for(int j=0;j<Procs[i].Snum;j++) {
Procs[i].Total+=Procs[i].Segments[j].Pnum; } pageCount+=Procs[i].Total; } for(int i=0;i<segnum-1;i++) { pageCount+=Procs[procnum-1].Segments[i].Pnum; } if(pageCount+pagenum==pageTotal) { if(memSize % blockSize !=0) {
cout<<"无此进程,无法进行地址转换!"<<endl; } if(Procs[procnum-1].isInMem !=1) {
cout<<"此进程不在内存中,地址转换失败!"<<endl; }
8
武汉理工大学《操作系统》课程设计
if(segnum<=0 || segnum > Procs[procnum-1].Snum) {
3.1 相关数据结构的定义
long memSize;
//内存的大小
int blockSize;
//内存块的大小
int blockCount;
//内存块的总数目
int prosCount;
//进程的数目
int pageTotal;
//总页数
int pageCount=0;
int count=0;
struct Page
}
if(pageCount+Procs[i].Total>pageTotal)
{
Procs[i].isInMem=0;
cout<<"内存空间不足,进程 p"<<i+1<<"及以后的内存分配失败!"<<endl;
break;
}
else
{
for(int j=0;j<Procs[i].Snum;j++)
{
号 S 对应的段表项; 3、查看该段的状态位,若该段不再内存中,则产生“缺段中断”,并将所缺段调
入内存,如此时内存中没有空闲空间,则需要进行置换; 4、用逻辑地址中的页号 P 与页表长度进行比较,若页号大于页表长度,则产生
“越界中断”; 5、由该段的页表始址,找到该段的页表; 6、从页表中得到页号 P 对应的页表项,查看该页的状态位,如果该页不在内存
3.5 地址转换函数
void addrExchange() {
cout<<"请输入进程号:p"; cout<<"请输入逻辑地址 "<<endl; cout<<"段号:"; cout<<"段内页号:"; cout<<"页内位移:"; if(procnum<=0 || procnum>prosCount) {
void allocMem()
{
cout<<"内存空间分配中"<<endl;
wait();
//等待时间计数函数
for(int i=0;i<prosCount;i++)
{
Procs[i].Total=0;
for(int j=0;j<Procs[i].Snum;j++)
{
Procs[i].Total+=Procs[i].Segments[j].Pnum;
中,则产生缺页中断,如果内存中无空闲空间,则需要进行置换; 7、得到该页在内存中的存储块号,并与逻辑地址中的页内位移构成物理地址; 8、根据得到的物理地址,访问数据区的数据。
2.2 程序流程图
3
武汉理工大学《操作系统》课程设计 4
武汉理工大学《操作系统》课程设计
3 主要函数及其实现
本程序在 visual studio 2010 C++下完成;
在段页式存储管理系统中,段表包含这样几个基本项:段号,状态,该段的 页表长度,页表始址;页表包含的基本项是:页号,状态,块号。段页式管理中 段表,页表以及内存的关系如下图:
1.2.3 动态地址变换过程
在段页式存储管理系统中,要对内存中的指令或数据进行一次存取操作至少 需要访问 3 次内存。第一次是由段表寄存器得到段表始址去访问段表,然后取出 对应段的页表地址。第二次则是访问页表得到所要访问的物理地址。只有在访问 了段表和页表之后,,第三次才能访问真正要访问的物理单元。段页式存储管理
cout<<"请输入进程 p"<<i+1<<"的段数:";
6
武汉理工大学《操作系统》课程设计
for(int j=0;j<Procs[i].Snum;j++)
{
cout<<"请输入第"<<j+1<<"段的页数:";
cin>>Procs[i].Segments[j].Pnum;
}
}
}
3.4 内存的分配函数
Fra Baidu bibliotek
//进程数组的定义
3.2 内存的大小、块的大小的初始化函数
void init()
5
武汉理工大学《操作系统》课程设计
{ cout<<"内存大小、内存块的大小、初始化"<<endl; cout<<"请输入内存的大小(正整数):"; while(memSize<=0) { cout<<"内存大小输入有误,请重新输入:"; } cout<<"请输入内存块的大小(大于 0,小于等于内存大小):"; while(blockSize<=0 || blockSize>memSize) { cout<<"内存块大小输入有误,请重新输入:"; } if(memSize % blockSize ==0) blockCount=memSize / blockSize; else blockCount=memSize / blockSize + 1; pageTotal=blockCount;
2
武汉理工大学《操作系统》课程设计
系统地址变换如下所示:
2 整体功能及设计
2.1 程序思路
在段页式存储管理系统中,逻辑地址转换成物理地址并访问数据区是按一下 步骤进行的: 1、对于给定的逻辑地址,用段号 S 与段表寄存器中段表长度进行比较,若段号
大于段表长度,则产生“越界中断”; 2、通过段表寄存器中的段表始址,找到该段在内存中的段表,从段表中找出段
cout<<"该逻辑地址对应的物理地址为:"<<address<<endl;
}
3.6 主函数
int main()
{
char c='y';
cout<<"段页式虚拟存储器的地址转换"<<endl;
init();
//调用内存的大小、块的大小的初始化函数
applyMem();
//调用进程个数、段数以及段内地址的赋值函数
当程序中要转换进程号 p1 段号为 3 段内页号为 2 页内位移为 2 的地址时, 其地址为:
1.2 段页式存储的原理 1.2.1 虚地址的构成
在段页式管理中,一个进程仍然拥有一个自己的二维地址空间,这与段式管 理时相同。首先,一个进程中所包含的具有独立逻辑功能的程序或数据仍被划分 为段,并有各自的段号 s,这反映和继承了段式管理的特征。其次,对于段 S 中 的程序或数据,则按照一定的大小(页大小)将其划分为不同的页,和页式系统 一样,最后不足一页的部分仍然占一页,这反映和继承了页式管理的特征。从而, 段页式管理时的进程的逻辑地址空间中的逻辑地址由三部分组成:即段号 s,页 号 p 和页内相对地址 d,如下所示:
s
p
d
对于这三个部分组成的虚拟地址来说,程序员可见的仍是段号 s 和段内相对地址 w。p 和 d 是由地址变换机构把高几位解释成页号 P,以及把剩下的低位解释为页 内地址 d 而得到的。
1
武汉理工大学《操作系统》课程设计
1.2.2 段表和页表的构成
为了实现段页式管理,系统必须为每个作业或进程建立一张段表,管理内存 分配与释放,缺段处理,存储保护和地址变换。另外,由于一个段又被划分成了 若干页,每个段又必须建立一张页表,把段中的虚页变换成内存中的实际页面。 显然,与页式管理时相同,页表中也要有实际缺页中断处理和页面保护等功能的 表项。另外由于在段页式管理中,页表不在属于进程而是属于某个段,因此,段 表中应有专项指出该段所对应页表的页表始址和页表长度。
7
武汉理工大学《操作系统》课程设计
pageCount+=Procs[i].Segments[j].Pnum; for(int k=0;k<Procs[i].Segments[j].Pnum;k++) {
Procs[i].Segments[j].Pages[k].block = count; count++; } } Procs[i].isInMem = 1; cout<<"进程 p"<<i+1<<"已调入内存!"<<endl; } } cout<<endl; }
if(disp<=0 || disp>memSize % blockSize) {
cout<<"页内偏移地址越界,地址转换失败!"<<endl; }
9
武汉理工大学《操作系统》课程设计
}
else
{
if(disp<=0 || disp>blockSize)
{
cout<<"页内偏移地址越界,地址转换失败!"<<endl;
4.1 程序的测试用例
测试用例如下:
4.1.1 数据的初始化
内存的大小 :100
内存块的大小:4
进程的个数 :2
进程 p1 的段数:3
第 1 段的页数 :1
第 2 段的页数 :2
第 3 段的页数 :3
进程 p2 的段数:2
第 1 段的页数 :2
第 2 段的页数 :2
4.1.2 需转换的进程数据
(1)进程号 p1
武汉理工大学《操作系统》课程设计
模拟设计段页式虚拟存储 管理中地址转换
1 程序需求分析
1.1 段页式管理的提出
段式和页式存储管理各有优缺点,页式系统能有效地提高内存的利用率,而 段式系统能更好地满足用户的需要。如果对两种存储管理方案“各取所长”,则 可将两者结合成一种新的存储管理系统,于是段页式存储管理系统应运而生。段 页式存储管理系统既有段式系统便于实现段的共享,段的保护,动态链接和段的 动态增长等一系列优点,又能像页式系统那样,很好地解决内存的外碎片问题。
allocMem();
//调用内存的分配函数
cout<<"地址转换"<<endl;
10
武汉理工大学《操作系统》课程设计
while(c=='y' || c=='Y')
{
addrExchange();
//调用地址转换函数
cout<<"继续进行地址转换?(是-y/否-n):";
}
return 0;
}
4 运行结果与运行情况分析
段号 :3
段内页号:2
页内位移:2
(2)进程号 p2
段号 :2
段内页号:3
11
武汉理工大学《操作系统》课程设计
页内位移:4
4.2 程序的运行结果
下图为地址转换成功时的程序运行界面:
下图为地址转换不成功时的程序运行界面:
12
武汉理工大学《操作系统》课程设计
4.3 程序运行结果分析
程序初始时对相关数据初始化后,内存各个进程的分配情况如下: 内存中有 25 页,p1 进程占用 0~5 页;p2 进程占用 6`9 页:
cout<<"段地址越界,地址转换失败!"<<endl; } if(pagenum<=0 || pagenum>Procs[procnum-1].Segments[segnum-1].Pnum) {
cout<<"段内页地址越界,地址转换失败!"<<endl; } for(int i=0;i<procnum-1;i++) {
}
}
}
else
{
if(disp<=0 || disp>blockSize)
{
cout<<"页内偏移地址越界,地址转换失败!"<<endl;
}
}
address=(Procs[procnum-1].Segments[segnum-1].Pages[pagenum-1].blo
ck)*blockSize+disp-1;
}
3.3 进程个数、段数以及段内地址的赋值函数
void applyMem() {
cout<<"内存空间申请"<<endl; cout<<"请输入进程的数目(大于 0,小于等于 10 的整数):"; while(prosCount<=0 || prosCount>ProTableSize) {
cout<<"进程数目输入有误,请重新输入:"; } for(int i=0;i<prosCount;i++) {