操作系统之存储管理:分页存储管理&地址变换【全面代码&原理解释】


在这里插入图片描述


一、实验目的与要求

掌握分页存储管理的基本原理及分页存储管理中的地址变换过程,编制一个模拟地址变换过程的程序并能采用先进先出页面置换算法实现页面置换。


二、实验内容

1、复习分页存储管理的基本概念、基本原理、及地址变换过程。
2、编制一个模拟地址变换过程并能进行缺页中断处理和页面置换的程序。


三、实验原理

在页式内存管理中,将程序空间分成大小相同的页,物理内存空间也分成大小相同的块,页的大小和块的大小一致。当程序装入内存准备运行时,逻辑上连续的页可以装入不连续的物理块中(当然也可以是连续的物理块)。

程序执行时,为了正确地访问内存物理地址,需要使用页表,该表在创建进程由操作系统在内存特定区域创建,并根据当时的内存分配情况,动态地将程序中的各页装入内存的空闲块中,并填上页表。

在支持页式管理的系统中,为了加快地址映射速度,通常都把页表的全部或一部分放在快表中,由硬件自动完成地址映射过程。程序的逻辑地址可表示为:P W

其中P为页号,W为页内位移。假设块或页的大小为2nB(n为整数),则W的取值范围为0-2n-1。 给定一个逻辑地址LA,可以用两种方法得到P和W。
(1)P=LA>>n,W=LA&(2n-1)
(2)P=INT(LA/2n) ,W=LA % 2n

当取得页号P 后查页表,能得到这一页装在内存中的块号B,可采用两种方法计算物理地址PA。
(1)PA=(B<<n)|W
(2)PA=B×2n+W 由于在CPU执行逻辑指令的速度远高于执行算术指令的,故采用方法一进行地址映射。

在进程执行的过程中,如果访问的页暂时不在内存,便产生缺页中断,由操作系统负责把所缺的页从外存调入内存,然后再重复执行产生缺页中断的指令,从而实现请求页式管理。

在调页的过程中,如果内存还有空闲的物理块时,当然可以给该进程追加内存分配;如果当内存中没有空闲的物理块时就需要淘汰一个当前在内存的“老页”,这个“老页”可以属于该进程本身,也可能属于别的进程。为了降低置换算法的复杂性而又不对其它进程产生影响,本实验采用前者,即局部置换方法。这样便可以在一个比较小的内存空间里运行一个较大的进程,从而实现虚拟存储器。


四、程序代码

#include <bits/stdc++.h>
using namespace std;
#define m 3				//实际为该作业分配的主存块块数
#define page_length 5	//页表实际长度
struct  //页表
{
	int lnumber;	//页号
	int pnumber;	//该页所在主存块的块号
	int flag;		//状态位,"1"表示该页在主存,"0"表示该页不在主存
	int write;		//修改位,"1"表示该页内容被修改过,"0"表示该页内容末修改过
	int dnumber;	//该页存在外存位置,即磁盘块号
}page[page_length];
int p[m];			//存放在主存中页的页号
int head;			//主存中页号队列p首指针

void page_interrupt(int lnumber) /*缺页中断处理函数,采用FIFO页面置换算法*/
{
  int j;
  printf("发生缺页中断* %d\n",lnumber);
  /*淘汰页*/
  j=p[head];
  p[head]=lnumber;/* 装入替换后的新页号*/
  head=(head+1)%m;
  if (page[j].write==1)
  printf("将页 %d写回磁盘第%d块\n",j,page[j].dnumber);
  /*修改页表*/
  page[j].flag=0;/* 第j页被换出,第j页存在标志改为"0"*/
  page[lnumber].pnumber=page[j].pnumber;/* 第lnumber页装入原来第j页所在的物理块*/
  page[lnumber].flag=1;/* 第lnumber页存在标志改为"1"*/
  page[lnumber].write=0;/* 第lunmber页修改标志改为"0"*/
  printf("淘汰主存块%2d中的页%2d,从磁盘第%d块中调入页%2d\n", page[j].pnumber,j,page[lnumber].dnumber,lnumber);
}/*缺页中断处理函数结束*/

void command(unsigned laddress,int write) /*命令处理函数*/
{
  unsigned paddress,ad,pnumber;//分别存放物理地址、页内地址和外存地址(盘块号);
  int lnumber;//存放页号;
  lnumber=laddress>>10;//页号=逻辑地址/2^10                 /*先计算出页号(高6位)和页内地址(低10位);*/
  ad=laddress%0x3ff;//页内地址利用位运算来取出后10位           
kk:
  if(lnumber>=page_length)    /*判断页号是否越界,若越界,显示越界不再进行地址变换;*/
    {
        printf("超出页长,不存在该页\n");
        return;
    }
    if(page[lnumber].flag==1)   /*若访问的页在内存,查找对应的物理块,计算物理地址;若不在内存,先调用page_interrupt(int lnumber)进行页面置换,再进行地址变换。*/
 
    {
        pnumber=page[lnumber].pnumber;
        paddress=pnumber<<10|ad;
        printf("逻辑地址是:%d,对应物理地址是:%d\n",laddress,paddress);
        if(write==1)
            page[lnumber].write=1;
    }
    else
    {
        page_interrupt(lnumber);
        goto kk;
    }
}

int main()  //主函数
{
	int write;
	unsigned laddress;
	//初始化页表,分配3个物理块。数据可改
	page[0].lnumber=0;page[0].pnumber=4;page[0].flag=1;page[0].write=0;page[0].dnumber=4;
	page[1].lnumber=1;page[1].pnumber=3;page[1].flag=1;page[1].write=0;page[1].dnumber=20;
	page[2].lnumber=2;page[2].pnumber=7;page[2].flag=1;page[2].write=0;page[2].dnumber=18;
	page[3].lnumber=3;page[3].pnumber=0;page[3].flag=0;page[3].write=0;page[3].dnumber=6;
	page[4].lnumber=4;page[4].pnumber=0;page[4].flag=0;page[4].write=0;page[4].dnumber=9;
	head=0;			//开始指向p[0]
	p[0]=0;p[1]=1;p[2]=2;  //3个物理块中所放的页为0页、1页、2页
	cout<<"**********************************"<<endl;
	cout<<"**************23夏旭**************"<<endl;  
	cout<<"**********************************"<<endl; 
	while(1)
	{
		cout<<"输入指令性质(1-写指令,0-读指令,其他--结束程序运行)和逻辑地址:";
		cin>>write;
		cin>>laddress;
		if(write==0||write==1)	command(laddress,write);
		else  break;
	}
}

五、结果分析

在这里插入图片描述

1、输入 1 500:
首先取出逻辑地址500的页号(高六位)和页内地址,页号只需移位操作即可得到,页内地址通过逻辑地址与2n-1进行按位与操作即可得到,500移位后的页号为0没有越界,块号为4,块号左移10位后再与页内地址进行按位与操作,就可以得到物理地址:4*1024+500=4596。

2、输入 1 3500:
页号为3,没有越界,但是page[3]对应的flag=0,缺页中断,调用缺页中断处理函数,将原来的p[ ]数组里的首元素淘汰,用一个变量j记录其值,然后将这个位置改为缺页页号,将该缺页页号的flag改为1,表示该页存在主存,将write改为0,表示该页未修改,接着输出被淘汰的页号及其主存块值,新的页号及其主存块值,这样缺页中断函数结束,通过goto kk回到取逻辑地址的页号和页内地址的地方,过程同上,得出页号为3,此时他的快号为4,接着将逻辑地址和2n-1按位与得出页内地址,将快号左移十位在与页内地址按位与得到物理地址:4524

3、输入 1 4500:
页号为4,没有越界,但是page[4]对应的flag为0,即该页不在主存,缺页中断,调用缺页中断处理函数,将原来的p[ ]数组里的首元素淘汰,用一个变量j记录其值,然后将这个位置改为缺页页号,将该缺页页号的flag改为1,表示该页存在主存,将write改为0,表示该页未修改,接着输出被淘汰的页号及其主存块值,新的页号及其主存块值,这样缺页中断函数结束,通过goto kk回到取逻辑地址的页号和页内地址的地方,过程同上,得出页号为4,此时他的快号为3,接着将逻辑地址和2n-1按位与得出页内地址,将快号左移十位在与页内地址按位与得到物理地址: 3476

4、输入 1 6000:
页号为5,越界,结果输出 “超出页长,不存在该页”。


六、实验小结

通过此次实验,我能够编制一个模拟地址变换过程并能进行缺页中断处理和页面置换的程序,更加熟悉分页存储管理的基本原理及分页存储管理中的地址变换过程。了解如何根据当时的内存分配情况,动态地将程序中的各页装入内存的空闲块中,并填上页表等重要的知识。


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米莱虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值