第一题:模拟分页式存储管理中硬件的地址转换和产生缺页中断。
( 1 ) 分页式虚拟存储系统是把作业信息的副本存放在磁盘上,当作业被选中时,可把 作业的开始几页先装入主存且启动执行。为此,在为作业建立页表时,应说明哪 些页已在主存,哪些页尚未装入主存,页表的格式为: 页号、标志、主存块号、在磁盘上的位置 (2) 作业执行时,指令中的逻辑地址指出了参加运算的操作存放的页号和单元号,硬 2 件的地址转换机构按页号查页表,若该页对应标志为“ 1 ”,则表示该页已在主存, 这时根据关系式: 绝对地址 = 块号×块长 + 单元号 计算出欲访问的主存单元地址。如果块长为 2 的幂次,则可把块号作为高地址部 分,把单元号作为低地址部分,两者拼接而成绝对地址。若访问的页对应标志为 “ 0 ”,则表示该页不在主存,这时硬件发“缺页中断”信号,有操作系统按该页 在磁盘上的位置,把该页信息从磁盘读出装入主存后再重新执行这条指令。 (3) 设计一个“地址转换”程序来模拟硬件的地址转换工作。当访问的页在主存时, 则形成绝对地址,但不去模拟指令的执行,而用输出转换后的地址来代替一条指 令的执行。当访问的页不在主存时,则输出“ * 该页页号”,表示产生了一次缺页 中断 ......第二题:用先进先出(FIFO)页面调度算法处理缺页中断。
......
Page.java
package 虚拟存储;
//页表
public class Page {
public int pageNo; //页号
public int flag;//标记是否放入主存
public char blockNo;//主存块号
public int diskAdd;//在磁盘上的位置
public int revise;//修改位
//构造方法
public Page(int pageNo,int flag,char blockNo,int diskAdd,int revise) {
this.pageNo=pageNo;
this.flag=flag;
this.blockNo=blockNo;
this.diskAdd=diskAdd;
this.revise=revise;
}
public void setRevise(int revise) {
this.revise=revise;
}
public void setBlockNo(char blockNo) {
this.blockNo=blockNo;
}
public void setFlag(int flag) {
this.flag=flag;
}
public char getBlockNo() {
return blockNo;
}
public int getPageNo() {
return pageNo;
}
@Override
//改写父类方法,输出页表
public String toString() {
return "页号:" + pageNo + " 是否放入主存:" +flag+ " 主存块号:" +blockNo+ " 修改位:"+revise+" 在磁盘上的位置:" +diskAdd;
}
}
JobWork.java
package 虚拟存储;
import java.util.List;
//指令类
public class JobWork {
int jobNo;//指令序号
public int pageNo;//页号
public int unitNo;//单元号
public boolean isInter=false;//所需页是否在主存
public int xiugai;//页面是否被修改 0表示不修改 1表示修改
public JobWork(int jobNo,int pageNo,int unitNo, int xiugai) { //构造函数
this.jobNo=jobNo;
this.pageNo=pageNo;
this.unitNo=unitNo;
this.xiugai=xiugai;
}
public boolean getIsInter() {
return isInter;
}
@Override
//改写父类方法,输出指令信息
public String toString() {
return "指令"+jobNo+" 页号:"+pageNo+" 单元号:"+unitNo+" 是否修改页面:"+xiugai;
}
public void work(List inter) { //指令执行
//遍历链表 页是否已经在主存
for(int i=0;i<=3;i++) {
int tempNo=inter.get(i).getPageNo();
//所用到的页在主存
if(tempNo==pageNo) {
//绝对地址:块号*128+单元号
int add=inter.get(i).getBlockNo()*128+unitNo;
System.out.println(" 绝对地址:"+add);
if(xiugai==1)
inter.get(i).setRevise(1);//设置修改位为1
isInter=true;
return;
}
}
System.out.println(" *************");
return;
}
}
Inter.java(内存或者主存?)
package 虚拟存储;
import java.util.linkedList;
public class Inter {
//链表存储调入主存的页
public linkedList list=new linkedList();
//初始化
public void init(Page[] page) {
for(int i=0;i<=3;i++) { //主存大小为4
list.add(page[i]);
}
}
//缺页中断处理 先进先出
public void FIFO(JobWork job,Page[] page) {
//去掉链表首元素
char alter=list.get(0).getBlockNo();//获取块号
list.get(0).setFlag(0); //标志置为0
list.get(0).setBlockNo('*'); //块号置为*
list.remove(0);
//链表尾部插入新页
int xuyao=job.pageNo;//获取所需页的页号
for(int i=0;i<=6;i++) {
if(page[i].getPageNo()==xuyao) {
page[i].setBlockNo(alter);//分配块号
page[i].setFlag(1);//标志置为1
list.addLast(page[i]);
}
}
}
//展示主存中所存页的页表
public void displayList() {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
for(int m=0;m<=3;m++) {
System.out.println(list.get(m));
}
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
}
Test.java
package 虚拟存储;
public class Test {
public static void main(String[] args) {
Page[] page=new Page[7];
//7页作业 用数组存储
page[0]=new Page(0,1,'5',11,0);
page[1]=new Page(1,1,'8',12,0);
page[2]=new Page(2,1,'9',13,0);
page[3]=new Page(3,1,'1',21,0);
page[4]=new Page(4,0,'*',22,0);
page[5]=new Page(5,0,'*',23,0);
page[6]=new Page(6,0,'*',121,0);
Inter inter=new Inter();
//内存初始化
inter.init(page);
//12条指令 数组存储
JobWork[] job=new JobWork[12];
job[0] =new JobWork( 1,0,70,1);
job[1] =new JobWork( 2,1,50,1);
job[2] =new JobWork( 3,2,15,1);
job[3] =new JobWork( 4,3,21,0);
job[4] =new JobWork( 5,0,56,0);
job[5] =new JobWork( 6,6,40,1);
job[6] =new JobWork( 7,4,53,1);
job[7] =new JobWork( 8,5,23,1);
job[8] =new JobWork( 9,1,37,0);
job[9] =new JobWork(10,2,78,0);
job[10]=new JobWork(11,4, 1,1);
job[11]=new JobWork(12,6,84,0);
inter.displayList();
for(int n=0;n<=11;n++) {
System.out.print(job[n]);
job[n].work(inter.list);
if(!job[n].getIsInter()) {
//所需页面不在主存 FIFO算法
inter.FIFO(job[n], page);
inter.displayList();
System.out.print(job[n]);
job[n].work(inter.list);
}
}
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
for(int p=0;p<=6;p++) {
System.out.println(page[p]);
}
}
}
运行结果



