【操作系统】段页式虚拟存储管理实验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

  • 7
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用请求管理中的面置换算法模拟存储器管理的C++程序示例: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; // 定义表项 struct PageTableEntry { int page_number; // 号 int frame_number; // 帧号,-1表示未分配 int reference; // 参考位,0或1 int modify; // 修改位,0或1 }; // 定义面置换算法类 class PageReplacementAlgorithm { public: virtual int getReplacePage() = 0; // 获取要置换的面 virtual void updatePageTable(PageTableEntry& page_table_entry) = 0; // 更新表 }; // 定义FIFO面置换算法类 class FIFOPageReplacementAlgorithm : public PageReplacementAlgorithm { public: FIFOPageReplacementAlgorithm(int frame_count) { frame_count_ = frame_count; frame_index_ = 0; page_frames_.resize(frame_count_, -1); } int getReplacePage() override { int replace_page = page_frames_[frame_index_]; frame_index_ = (frame_index_ + 1) % frame_count_; return replace_page; } void updatePageTable(PageTableEntry& page_table_entry) override { page_frames_[frame_index_] = page_table_entry.frame_number; } private: int frame_count_; int frame_index_; vector<int> page_frames_; }; // 定义LRU面置换算法类 class LRUPageReplacementAlgorithm : public PageReplacementAlgorithm { public: LRUPageReplacementAlgorithm(int frame_count) { frame_count_ = frame_count; page_frames_.resize(frame_count_, -1); } int getReplacePage() override { int replace_page = page_frames_.back(); page_frames_.pop_back(); return replace_page; } void updatePageTable(PageTableEntry& page_table_entry) override { int frame_number = page_table_entry.frame_number; auto iter = find(page_frames_.begin(), page_frames_.end(), frame_number); if (iter != page_frames_.end()) { page_frames_.erase(iter); } page_frames_.insert(page_frames_.begin(), frame_number); } private: int frame_count_; vector<int> page_frames_; }; // 定义存储器管理类 class MemoryManager { public: MemoryManager(int page_count, int frame_count, PageReplacementAlgorithm* page_replacement_algorithm) { page_count_ = page_count; frame_count_ = frame_count; page_replacement_algorithm_ = page_replacement_algorithm; page_table_.resize(page_count_); for (int i = 0; i < page_count_; i++) { page_table_[i].page_number = i; page_table_[i].frame_number = -1; page_table_[i].reference = 0; page_table_[i].modify = 0; } frame_table_.resize(frame_count_, -1); } void accessPage(int page_number, bool modify) { PageTableEntry& page_table_entry = page_table_[page_number]; if (page_table_entry.frame_number == -1) { // 未分配帧,需要置换面 int replace_page = page_replacement_algorithm_->getReplacePage(); int replace_frame = frame_table_[replace_page]; if (replace_frame != -1) { // 释放帧 frame_table_[replace_page] = -1; page_table_[replace_page].frame_number = -1; page_table_[replace_page].reference = 0; page_table_[replace_page].modify = 0; } // 分配帧 page_table_entry.frame_number = replace_frame; page_table_entry.reference = 1; page_table_entry.modify = modify ? 1 : 0; frame_table_[page_number] = replace_frame; page_replacement_algorithm_->updatePageTable(page_table_entry); } else { // 已分配帧,更新参考位和修改位 page_table_entry.reference = 1; if (modify) { page_table_entry.modify = 1; } } } void printPageTable() { cout << "Page Table:" << endl; cout << "Page Number\tFrame Number\tReference\tModify" << endl; for (int i = 0; i < page_count_; i++) { PageTableEntry& page_table_entry = page_table_[i]; cout << i << "\t\t" << page_table_entry.frame_number << "\t\t" << page_table_entry.reference << "\t\t" << page_table_entry.modify << endl; } } private: int page_count_; int frame_count_; vector<PageTableEntry> page_table_; vector<int> frame_table_; PageReplacementAlgorithm* page_replacement_algorithm_; }; // 测试程序 int main() { int page_count = 10; int frame_count = 4; PageReplacementAlgorithm* page_replacement_algorithm = new LRUPageReplacementAlgorithm(frame_count); MemoryManager memory_manager(page_count, frame_count, page_replacement_algorithm); // 访问面 memory_manager.accessPage(0, false); memory_manager.accessPage(1, false); memory_manager.accessPage(2, false); memory_manager.accessPage(3, false); memory_manager.accessPage(4, false); memory_manager.accessPage(5, false); memory_manager.accessPage(6, false); memory_manager.accessPage(7, false); memory_manager.accessPage(8, false); memory_manager.accessPage(9, false); memory_manager.accessPage(0, true); memory_manager.accessPage(1, true); memory_manager.printPageTable(); return 0; } ``` 该程序实现了请求管理中的面置换算法,包括FIFO和LRU两种算法。程序先创建一个MemoryManager对象,然后通过访问面来测试程序。最后输出面表的内容。 需要注意的是,该程序仅为示例代码,实际应用中需要根据具体情况进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值