【操作系统】段页式虚拟存储管理实验C、C++(代码)

编写程序完成段页式虚拟存储管理分配、地址重定位

段页式存储管理方式即先将用户程序分成若干个段,再把每个段分成若干个页,并为每一个段赋予一个段名。

#include <stdlib.h>
 #include <stdio.h>
 #include <iostream>
 #define memMax 10240//最大内存,10M
 using namespace std;
 void prspm();//一般在内存中给出一块固定的区域放置段表
 int memLen;//内存大小
 int pageLen;//页的大小
 typedef struct pageL{//页表
 int pageNum;//页号
 int MemPgnum;//页面号(内存页面号)
 int pageFlag;
}pageL;
 struct pageLH{
 int length;
 pageL pageList[1024];
}pageLH;
 struct segmentL{//段的大小与划分不归我管,而且段表的大小是一开始就建立好的,页表在内存中有一块固定的存储区。页表的大小由进程或作业的长度决定 
 int segNum;//段号
 int length;//段长即多少页
 int rw;//访存控制
 int ioflg;//内外标识
 int count;//访问位
 pageL* startAddr;//起始位置
 int segmentFlag;
 }segPagList[100];//段表,因为段表是固定的内存区,所以直接设为数组

 struct segmentLH{
 int length;
 segmentL segPagList[200];//段表,因为段表是固定的内存区,所以直接设为数组200差不多了1024页,每段5页
}segmentLH;

 char m[10240];//无法使用链表法,char类型是一个字节,节省空间,值表示页是否被使用
 int findldlePage(){//返回找到空闲内存页的第一个位置
 int j=1;
 for( int i=0;i<memLen/pageLen;i++){
 if(m[i]==0){
 m[i]=1;
 return i;
}
j++;
}
 if (j==memLen/pageLen){
 printf("所有的内存已经使用完了!请输入数字已选择相应的置换算法!!");
}
}
 int totalldlePage(){
 int n=0;
 for(int i=0;i<memLen/pageLen;i++){
if(m[i]==0)n++;
}
 return n;
}
 int findldleSegAndWrite(int segNum,int segLen){
 int i;
for(i=0;i<200;i++){
 if(segmentLH.segPagList[i].segmentFlag==0){
 segmentLH.segPagList[i].segNum=segNum;
 segmentLH.segPagList[i].length=segLen;//段长,即分多少页
 segmentLH.segPagList[i].segmentFlag=1;
 return i;
}
}
 printf("段表没有可以填写的段!");
 return -1;//没有可以填写的段就返回-1
}
 int findSeriesldlePageList(int q){//参数q表示需要连续空间的页数返回值为分配数组起始标号
 int t,n=0;
 L1:
 for(t=0;t<q;t++){
 if(pageLH.pageList[n+t].pageFlag!=0){
 n++;
 if(n<1024-q)goto L1;
 printf("没有可用的连续页表空间!");
}
}
for(t=0;t<q;t++){//将已分配到的页表,标记为正在使用
 pageLH.pageList[t+n].pageFlag=1;
}
 return n;
}
 void single(){//怎样判断内存区有没有空闲
 int flag=1;
 int q=0; 
 int N=0;
 int p;
 int segNum,length;
 printf("请输入段的个数:\n");
 scanf("%d",&N);
 printf("请依次输入段长:\n");
 for(int z=1;z<=N;z++){
 scanf("%d",&length);
 p=totalldlePage();//先看内存有没有足够的页进行分配,有:就先查找可用段,填写段表
 q=((length%pageLen==0)?(length/pageLen):((int)length/pageLen)+1);//程序要分多少页
 if(p>=q){//内存够分
 int i=findldleSegAndWrite(z,q);//找到可以填写的段,填写段长,段号
 int n=findSeriesldlePageList(q);//查找页表寻找连续q个页表空间,返回首地址
 p=p-q;//在上面的函数中已经将页面数减过了,只是没有反映到p中
 segmentLH.segPagList[i].startAddr=&pageLH.pageList[n];//填写段的页的开始地址,页表的第n项
 for(int j=n;j<q+n;j++){//填写页表的时候,页表的填写是连续的
 pageLH.pageList[j].pageNum=j-n+1;
 pageLH.pageList[j].MemPgnum=findldlePage();//返回找到空闲内存页的第一个位置,并将使用位置1
}
}
}
}
 void mapping(){
 int s,p,d;
 int i;
 printf("请输入段号,页号,页内地址:s,p,d\n");
 scanf("%d,%d,%d",&s,&p,&d);
 for(i=0;i<100;i++){
 if(segmentLH.segPagList[i].segNum==s){
 if( segmentLH.segPagList[i].length>p){
 if(d<pageLen*1024){
 printf("输入的地址正确:\n");
 int w=(segmentLH.segPagList[i].startAddr[p].MemPgnum-1)*1024*pageLen+d;
 printf("存页面号:%d\n",(segmentLH.segPagList[i].startAddr[p].MemPgnum-1));
 printf("%dB\n",w);
 return;
 }else{
 printf("偏移地址偏出该页!\n");
 return;
}
 }else{
 printf("没有该页\n");
 return;
}
}
if((i+1)>=100)printf("没有该段!\n");
}
}
 void swch(){
 int flag=1,f=0;
 while(flag){
 int n;
 printf("程序段处理----------------1\n");
 printf("地址转换------------------2\n");
 printf("显示段页存映射表----------3\n");
 printf("退出----------------------4\n");
 getchar();
 scanf("%d",&n);
 switch(n){
 case 1: single();f=1;break;
 case 2:if(f!=0)mapping();else printf("请先输入程序段!\n"); break;
 case 3:if(f!=0)prspm();else printf("请先输入程序段!\n");break;
 case 4: flag=0;break;
 default:printf("输入有误!\n");
}
}
}
 void prspm(){
 printf("--------段页内存映射表---------\n");
 printf("-------------------------------\n");
 for(int i=0;i<200;i++){
 if(segmentLH.segPagList[i].segmentFlag!=0){
 printf("段号:%d",segmentLH.segPagList[i].segNum);//段号 
 printf("  段长: %d\n",segmentLH.segPagList[i].length);//段长
for(int j=0;j<segmentLH.segPagList[i].length;j++){//页号页面号
 printf("%d_____%d_____\n",segmentLH.segPagList[i].startAddr[j].pageNum,segmentLH.segPagList[i].startAddr[j].MemPgnum);
}
 printf("\n");
}
}
 printf("-------------------------------\n");
}
 int main(){
 printf("初始化设置-----------------\n");
 printf("请指定内存的大小(kB):");
 scanf("%d",&memLen);
 printf("请设置页的大小(KB):");//一般来讲1--4KB
 scanf("%d",&pageLen);
for(int i=0;i<memLen;i++){//初始化内存列表
m[i]=0;
}
 pageLH.length=0;
 for(int i=0;i<200;i++)
 segmentLH.segPagList[i].segmentFlag=0;
 for(int i=0;i<1024;i++)
 pageLH.pageList[i].pageFlag=0;
 swch();
 system("pause");
 return 0;
}

测试输出

转载自段页式虚拟存储管理-20210401132441.doc-原创力文档段页式虚拟存储管理.doc,.. 专业资料 学 号: 课 程 设 计 题 目 段页式虚拟存储管理 学 院 计算机科学与技术 专 业 班 级 姓 名 指导教师 吴利军 2013 年 1 月 16 日 课程设计任务书 学生姓名: 指导教师: 吴利军 工作单位: 计算机科学与技术学院 题 目: 模拟设计段页式虚拟存储管理中地址转换 初始条件: 1.预备容:阅读操作系统的存管理章节容,理解段页式存储管理的思想及相应的分配主存的过程。 2.实践准备:掌握一种计算机高级语言的使用。 要求完成的主要任务: (包括课程设计工作量及其技术要https://max.book118.com/html/2021/0401/7163051003003110.shtm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值