操作系统,页式虚存管理,使用最近最久置换算法

1.要求:

① 指令序列的设定可以执行拟定,格式如表3;

② 在完成了FIFO换页策略后,可以选做LRU的换页策略,并进行比较;   

③ 作业允许的页框数m在不同情况下的缺页中断率;

④ 程序运行时显示地址转变和页面调入调出过程。

2.步骤:

① 设计页表及其数据结构:

    页号

    标志:是否在主存;

    页框号:设定页表在主存的位置;

    修改标志:设定页面在主存中是否修改过;

    磁盘上位置:设定页面在辅存中的位置;

例如:装入新页置换旧页时,若旧页在执行中没有被修改过,则不必将该页重写磁盘。因此,页表中增加是否修改过的标志,执行“存”指令和“写”指令时将对应的修改标志置成“1”表示修改过,否则为“0”表示未修改过。

②设计一个地址转换程序半模拟硬件的地址转换和缺页中断。

当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可以输出转换后的绝对地址来表示一条指令已执行完成。当访问的页不在主存中时,则输出“*页号”来表示硬件产生了一次缺页中断。

#pragma once
#include<stdio.h>
typedef struct page
{
	unsigned int pageid;
	unsigned int storage;
	unsigned int pageframe;
	unsigned int flag;
	unsigned int address;
}page;

typedef struct operate
{
	char operation;
	unsigned int pageid;
	unsigned int page_address;
}oprate;

//将已经在页表中的页号重新按最久未用排序
void insert(page a[],int i)
{	
	page temp;
	temp = a[i];
	for (int p = i; p >0; p--) {
		a[p] = a[p-1];
	}
	a[0] = temp;
}

//将新加入的放在最前面,相当于最久未用
void append(page a[],operate b,page reference[],int number) 
{
	int n = 0;
	page temp;
	unsigned int page_frame[4] = {5,8,9,1};
	for (int i = 0; i < 7; i++) {
		if (b.pageid == reference[i].pageid)
			temp = reference[i];
	}
	n = page_frame[number - 1];
	temp.pageframe = n;
	if (number == 1)
	{
		a[0] = temp;
	}
	if(number > 1)
	{
		for (int t = number-1; t > 0; t--)
		{
			a[t] = a[t - 1];
		}
		a[0] = temp;
	}
}

//格式输出
void print_f(page a[], int maxpage,int number)
{
	printf("当前页表内的页号为:\n");
	for (int m = 0; m < number; m++) 
	{
		printf("pageid:%d   storage:%d   pageframe:%d   flag:%d \n",a[m].pageid,a[m].storage,a[m].pageframe,a[m].flag);
	}
	printf("\n\n");
}

//置换操作
void page_exchang(page a[],page temp,int maxpage)
{
	temp.pageframe = a[maxpage - 1].pageframe;
	for (int i = maxpage-1; i > 0 ; i--)
	{
		a[i] = a[i - 1];
	}
	a[0] = temp;
}

//页表,新来的操作,页表里的元素个数,最大页表元素个数,参照表
void run_fifo(page a[], operate b, int &number, int maxpage, page reference[])
{
	int count_address = 0;           //绝对地址
	page temp;
	int flag_storage = 0;			//是否在内存
	int flag_cun = 0;				//存的标志
	char v[] = { 'c','q' };
	int j = -1;							//中断时取出页号
	if (b.operation == v[0])	flag_cun = 1;  //如果是存操作
	if (number < maxpage) {											//如果页表未满,执行以下
		printf("没有发生缺页中断\n");
		for (int i = 0; i < number; i++) 
		{
			if (b.pageid == a[i].pageid)                            //页号已经在页表中
			{														
				insert(a,i);									//改变页表内顺序
				count_address = a[0].pageframe*1024 + b.page_address;
				printf("绝对地址%d\n", count_address);						//输出绝对地址
				flag_storage = 1;
			}
		}															//新加入内存
		if (!flag_storage)
		{
			number += 1;                                         //内存中个数+1
			append(a, b, reference, number);					//按序排
			a[0].storage = 1;                                   //将在内存的标志改为1
			if (flag_cun) a[0].flag = 1;                        //如果操作是”存“,flag =1 
			count_address = a[0].pageframe*1024 + b.page_address;      //计算地址
			printf("绝对地址%d\n", count_address);						//输出绝对地址   
		}
	}
	else                                                            //页表已满
	{
		for (int i = 0; i < number; i++) {
			if (b.pageid == a[i].pageid) {                          //已在内存
				printf("没有发生缺页中断\n");
				insert(a,i);									//改变页表内顺序
				count_address = a[0].pageframe * 1024 + b.page_address;
				printf("绝对地址%d\n", count_address);
				flag_storage = 1;
			}
		}
		if(!flag_storage) 
		{					                                    //不在页表,发生置换
			printf("发生缺页中断\n");
			j = a[number - 1].pageid;		
			printf("\t中断页号: *%d\n", j);
			printf("\t输入页:%d\n",b.pageid);
			temp = reference[b.pageid];				            //改变a中数
			if (flag_cun)  temp.flag = 1;
			if(a[number-1].flag)	
				printf("第%d页之前为存指令,磁盘位置为:%d\n",a[number-1].pageid,a[number-1].address);
			temp.storage = 1;
			page_exchang(a,temp,maxpage);
			count_address = a[number-1].pageframe*1024 + b.page_address;
			printf("\t绝对地址%d\n", count_address);
		}
	}
}

// ConsoleApplication8.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include"标头.h"
#include <iostream>
#include<string>
using namespace std;

int main()
{
	int op_page_number = 0;
	int maxpage = 4;
	page a[4] = { NULL };
	page ref[7] = { {ref[0].pageid = 0 ,ref[0].storage = 0,ref[0].pageframe = NULL,ref[0].flag = 0,ref[0].address = 011},
			{ref[1].pageid = 1 ,ref[1].storage = 0,ref[1].pageframe = NULL,ref[1].flag = 0,ref[1].address = 012},
			{ref[2].pageid = 2 ,ref[2].storage = 0,ref[2].pageframe = NULL,ref[2].flag = 0,ref[2].address = 013},
			{ref[3].pageid = 3 ,ref[3].storage = 0,ref[3].pageframe = NULL,ref[3].flag = 0,ref[3].address = 021},
			{ref[4].pageid = 4 ,ref[4].storage = 0,ref[4].pageframe = NULL,ref[4].flag = 0,ref[4].address = 022},
			{ref[5].pageid = 5 ,ref[5].storage = 0,ref[5].pageframe = NULL,ref[5].flag = 0,ref[5].address = 023},
			{ref[6].pageid = 6 ,ref[6].storage = 0,ref[6].pageframe = NULL,ref[6].flag = 0,ref[6].address = 121} };
	operate op_page[12] = { {'+',0,070},{'-',1,050},{'*',2,015},{'c',3,021},
							{'q',0,056},{'-',6,040},{'y',4,053},{'+',5,023},
							{'c',1,037},{'q',2,78},{'+',4,001},{'c',6,84} };
	operate b;
	while (true)
	{	
		static int number = 0;
		printf("请输入调入第几个操作:\n");
		scanf_s("%d", &op_page_number);
		if (op_page_number == 99) break;
		if (op_page_number < 12) 
		{
			b = op_page[op_page_number];
			printf("执行操作:“%c”,页号为:%d ,页内地址为:%d\n",b.operation,b.pageid,b.page_address);
		}
		else
		{
			printf("请输入0—11的数\n\n");
			continue;
		}
		run_fifo(a,b,number,maxpage,ref);
		print_f(a,maxpage,number);
	}
	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值