模拟虚存管理

 

1、页表的数据结构


页号

标志

主存块号

修改位

外存地址


struct PageItem {
         unsigned pageID;         // 作业的页号
         unsigned outMAddr;    // 该页在外存上的地址
         bool state;                    // 该页是否调入内存,若未调入内存,则blockID和modify字段无效
         unsigned blockID;         // 该页对应的内存物理块号
         bool modify;                 // 该页是否被修改过
};


初始页表结构:

0 1 5 011 1
1 1 8 012 1
2 1 9 013 0
3 1 10 015 0
4 0 0 017 0
5 0 0 025 0
6 0 0 212 0
7 0 0 213 0


2、指令的数据结构


操作

页号

单元号(偏移量)


struct Instruction{
         string OPC;
         unsigned OPAPageID;
         unsigned OPAUnitID;
};


指令序列表:

+ 0 040
+ 1 050
* 2 016
存 3 022
取 0 054
- 6 040
移位 4 052
+ 5 022
存 1 034
取 7 056
+ 4 002
取 6 076



3、地址变换机构算法


 

4、缺页中断机构算法

采用FIFO置换算法,流程图如下:


 

队列进出情况:

页面走向

0

1

2

3

0

6

4

5

1

7

4

6

页框

0

0

0

0

 

1

2

3

6

4

 

5

 

1

1

1

 

2

3

6

4

5

 

1

 

 

2

2

 

3

6

4

5

1

 

7

 

 

 

3

 

6

4

5

1

7

 

6

 


5、源程序

#define_CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<queue>
#include<vector>
#include<string>
#include<cassert>
usingnamespace std;
 
const intPAGE_NUMBER = 8; // 作业所占的页数
const intBLOCK_NUMBER = 4; // 系统最多为作业分配的块数
const intBLOCK_SIZE = 64;     // 主存的每块长度
 
structPageItem {
         unsigned pageID;    // 作业的页号
         unsigned outMAddr;        // 该页在外存上的地址
         bool state;                          // 该页是否调入内存,若未调入内存,则blockID和modify字段无效
         unsigned blockID;    // 该页对应的内存物理块号
         bool modify;              // 该页是否被修改过
 
         // 默认构造函数
         PageItem()
                   :pageID(0),
                   blockID(0),
                   state(false),
                   modify(false),
                   outMAddr(0){}
 
         // 构造函数
         PageItem (
                   unsigned _pageID,
                   unsigned _blockID,
                   bool _state,
                   bool _modify,
                   unsigned _outMAddr)
                   :pageID(_pageID),
                   blockID(_blockID),
                   state(_state),
                   modify(_modify),
                   outMAddr(_outMAddr){}         
};
 
structInstruction {
         string OPC;
         unsigned OPAPageID;
         unsigned OPAUnitID;
};
 
//FIFOQueue的最大长度即系统最多为作业分配的块数BLOCK_NUMBER
voidInterrupt(vector<PageItem> &pageTable, queue<unsigned>&FIFOQueue, const unsigned visitPageID)
{
         assert(FIFOQueue.size() <=BLOCK_NUMBER);
 
         // 按书上给的一定队满,待改进
         if (FIFOQueue.size() == BLOCK_NUMBER)       // 队满则置换,换出队头
         {
                   unsigned num =FIFOQueue.front();         // 队头的页号num
                   pageTable[num].state = false;
                   if (pageTable[num].modify)
                   {
                            cout << "页" << num <<"被修改过,写回磁盘" << endl;
                   }
                   cout << "调页" << num <<"到磁盘" << endl;
                   FIFOQueue.pop();
                   pageTable[visitPageID].blockID= pageTable[num].blockID;
         }
         //pageTable[visitPageID].outMAddr =             // 队不满时实际应按内存分配算法给出该页分配到的物理块号
         cout << "调入页" << visitPageID<< endl;
         pageTable[visitPageID].state = true;
         pageTable[visitPageID].modify = false;
         FIFOQueue.push(visitPageID);
         // 实际还应修改内存分块表
}
 
intmain(int argc, char **argv)
{
         freopen("cin.txt","r", stdin);
 
         vector<PageItem>pageTable(PAGE_NUMBER);    // 作业在内存的页表
         queue<unsigned> FIFOQueue;                                              //系统为作业分配的块队列,元素为该页的页号
         for (int i = 0; i < PAGE_NUMBER;++i)
         {
                   cin >>pageTable[i].pageID
                            >>pageTable[i].state
                            >>pageTable[i].blockID
                            >> pageTable[i].outMAddr
                            >>pageTable[i].modify;
                   if (pageTable[i].state)
                   {
                            FIFOQueue.push(i);
                   }
         }
 
         Instruction ins;
         int cnt = 1;
         while (cin >> ins.OPC >>ins.OPAPageID >> ins.OPAUnitID)    //取指
         {
                   cout << "执行指令" << cnt++ <<endl;
                   unsigned visitPageID =ins.OPAPageID;  // 截取指令中的访问页号,来自MAR
                   if (ins.OPAPageID >=PAGE_NUMBER)
                   {
                            cout << "产生越界中断!" << endl;       // 应抛出异常?
                            return 1;
                   }
 
                   while(!pageTable[visitPageID].state)
                   {
                            cout << "产生缺页中断!" << endl;
                            Interrupt(pageTable,FIFOQueue, visitPageID);      // 缺页中断处理
 
                            // 须重复?
                            visitPageID =ins.OPAPageID; // 截取指令中的访问页号,来自MAR
                            if (visitPageID>= PAGE_NUMBER)
                            {
                                     cout<< "产生越界中断!" << endl;       // 应抛出异常?
                                     return 1;
                            }                          
                   }
 
                   unsigned visitBlockID =pageTable[visitPageID].blockID;
                   unsigned realAddr =visitBlockID * BLOCK_SIZE + ins.OPAUnitID;
                   cout << "绝对地址是" << realAddr <<endl;
                   if (ins.OPC == "存")
                   {
                            pageTable[visitPageID].modify= true;
                   }
                   cout << endl;
         }
 
         return 0;
}
 
/*cin.txt:
0 1 5 0111
1 1 8 0121
2 1 9 0130
3 1 10015 0
4 0 0 0170
5 0 0 0250
6 0 0 2120
7 0 0 2130
 
+ 0 040
+ 1 050
* 2 016
存 3 022
取 0 054
- 6 040
移位 4 052
+ 5 022
存 1 034
取 7 056
+ 4 002
取 6 076
*/

 

6、运行结果

执行指令1
绝对地址是360

执行指令2
绝对地址是562

执行指令3
绝对地址是592

执行指令4
绝对地址是662

执行指令5
绝对地址是374

执行指令6
产生缺页中断!
页0被修改过,写回磁盘
调页0到磁盘
调入页6
绝对地址是360

执行指令7
产生缺页中断!
页1被修改过,写回磁盘
调页1到磁盘
调入页4
绝对地址是564

执行指令8
产生缺页中断!
调页2到磁盘
调入页5
绝对地址是598

执行指令9
产生缺页中断!
页3被修改过,写回磁盘
调页3到磁盘
调入页1
绝对地址是674

执行指令10
产生缺页中断!
调页6到磁盘
调入页7
绝对地址是376

执行指令11
绝对地址是514

执行指令12
产生缺页中断!
调页4到磁盘
调入页6
绝对地址是588

请按任意键继续. . .


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一. 实验目的: 1.通过编写和调试存储管理模拟程序以加深对存储管理方案的理解。熟悉虚存管理的各种页面淘汰算法 2.通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 二.实验要求 实验程序由以下三大部分组成: (1) 通过随机数产生一个指令序列(实际上是指令的逻辑地址序列),共320条指令。指令的地址按下述原则生成: A:50%的指令是顺序执行的 B:25%的指令要实现向前跳转,均匀分布在前地址部分 C:25%的指令要实现向后跳转,均匀分布在后地址部分 具体的实施方法是: A:在[0,319]的指令地址之间随机选取一起点m B:顺序执行一条指令,即执行地址为m+1的指令 C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’ D:顺序执行一条指令,其地址为m’+1 E:在后地址[m’+2,319]中随机选取一条指令并执行 F:重复步骤A-E,直到320次指令 (2) 将每条指令的逻辑地址变换为页地址 设:页面大小为1K; 用户内存容量4页到32页; 用户虚存容量为32K。 在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为: 第 0 条-第 9 条指令为第0页(对应逻辑地址为[0,9]) 第10条-第19条指令为第1页(对应逻辑地址为[10,19]) ……………………………… 第310条-第319条指令为第31页(对应逻辑地址为[310,319]) 按以上方式,用户指令可组成32页。 (3) 分别使用FIFO算法和LFU算法,计算给用户进程的这32页分配4,5,…,32个页面(内存块)时其缺页率。
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值