实验题目:
(一)、模拟请求分页式存储管理中硬件的地址转换和产生缺页中断。
(二)、用先进先出页面调度算法处理缺页中断。
(三)、用最近最少用页面调度算法处理缺页中断。
代码如下:
#include "stdio.h" #include "stdlib.h" #include "string.h" #define m 4 typedef struct pagetable { int pagenum; //页号 int flag; //标志 1.装入主存 0.没有 int cachenum; //主存块号 int changeFlag; //修改标志 1.修改过。 0.没有 char location[5]; //在磁盘上的位置 }pagetable; typedef struct order{ char name[2]; int page; char unitNum[3]; }order; void readOrder(order ord[]) { char filename[10] ; int j = 0; FILE *fp = NULL; printf("请输入order的文件名:"); scanf("%s:", filename); fp = fopen(filename,"r"); //只读 if( fp== NULL) { printf("错误!"); exit(1); } printf("指令:\n"); printf(" %-8s %-8s %-8s \n", "操作","页号","单元号"); for(j ;j<12;j++) //不能再for内部定义变量 文件中是否也不能定义? { fscanf(fp," %s %d %s ", ord[j].name,&ord[j].page,ord[j].unitNum); printf(" %-8s %-8d %-8s \n", ord[j].name,ord[j].page,ord[j].unitNum); } fclose(fp); //关闭文件 fp = NULL; //需要指向空,否则会指向原打开文件地址 } void readPageTable(pagetable pt[]) { char filename[10] ; int j = 0; FILE *fp = NULL; printf("请输入页表的文件名:"); scanf("%s:", filename); fp = fopen(filename,"r"); //只读 if( fp== NULL) { printf("错误!"); exit(1); } printf("页表信息:\n"); printf(" %-8s %-8s %-8s %-8s %-8s\n", "页号","驻留标志","主存块号","修改标志","外存地址"); for(j ;j<7;j++) { fscanf(fp," %d %d %d %d %s ", &pt[j].pagenum,&pt[j].flag,&pt[j].cachenum,&pt[j].changeFlag,&pt[j].location); printf(" %-8d %-8d %-8d %-8d %-8s \n",pt[j].pagenum,pt[j].flag,pt[j].cachenum,pt[j].changeFlag,pt[j].location); } fclose(fp); //关闭文件 fp = NULL; //需要指向空,否则会指向原打开文件地址 } void absolulyAddress(order* ord, pagetable* pt ) { //绝对地址=块号×块长+单元号 int i = ord->page; //块号默认为128是2的幂次,所以高地值为块号,底地址为单元号 printf("address=%d%s\n\n",pt->cachenum,&ord->unitNum); } // 1. 求分页式存储管理中硬件的地址转换和产生缺页中断 void firstMethod(order ord[], pagetable pt[]){ int i = 0; printf("\n\n\n---------------- 1 ----------------\n\n"); for(i ;i<12;i++) { printf("“%s”的页号为%d 单元号为%s\n",ord[i].name,ord[i].page,ord[i].unitNum); if(pt[ord[i].page].flag==1){ //已在主存中 printf("该页已经在主存。绝对地址为:"); absolulyAddress(&ord[i],&pt[ord[i].page]); } else if(pt[ord[i].page].flag==0) //该页不在主存 产生中断信号 { printf("该页不在主存。产生中断信号:\n"); printf("*%d\n\n" , pt[ord[i].page].pagenum); //中断信号 pt[ord[i].page].flag = 1; //把该页信息从磁盘读出装入主存 pt[ord[i].page].cachenum = 10; //装入主存中,主存块号 设为10 i--; //重新执行该指令 } } } // 2. FIFO页面调度算法处理缺页中断 void FIFOMethod(order ord[], pagetable pt[]){ int i = 0; int j = 0; int k = 0; int p[m]; printf("\n\n\n---------------- 2 ----------------\n\n"); //初始化P for (i;i<m;i++) { p[i] = i; } i = 0; for(i ;i<12 ;i++) { printf("“%s”的页号为%d 单元号为%s\n",ord[i].name,ord[i].page,ord[i].unitNum); if(pt[ord[i].page].flag==1){ //如果该页标志是1 if (strcmp(ord[i].name, "存") == 0) { pt[ord[i].page].changeFlag = 1; } printf("该页已在主存, 其绝对地址为:"); absolulyAddress(&ord[i],&pt[ord[i].page]); } else if(pt[ord[i].page].flag==0) //如果该页标志不是1 { printf("该页不在主存。产生中断信号 *%d\n" ,pt[ord[i].page].pagenum); //中断信号 j = p[k]; if (pt[j].changeFlag == 1) //如果该页被修改过, 则将该页换出,将新页换入。 { printf("%d 页被换出, ",j); printf("%d 页被换入 \n\n", ord[i].page); }else if (pt[j].changeFlag == 0) { printf("%d 页被覆盖, ",j); printf("%d 页被换入 \n\n", ord[i].page); } pt[ord[i].page].flag = 1; pt[ord[i].page].cachenum = pt[p[k]].cachenum; pt[p[k]].flag = 0; //修改K的值 p[k] = ord[i].page; k = (k+1)%m; i--; } } //输出P i = 0; for (i;i<m;i++) { printf("p数组的值为: \n"); printf("P[i] = %d\n", p[i]); } printf("\n"); } // 3. LRU页面调度算法处理缺页中断 void LRUMethod(order ord[], pagetable pt[]){ int i = 0; int n = m-1; int p[m]; printf("\n\n\n---------------- 3 ----------------\n\n"); //初始化P for (i;i<m;i++) { p[i] = m-i-1; } i = 0; for(i ;i < 12 ;i++) { printf("“%s”的页号为%d 单元号为%s\n",ord[i].name,ord[i].page,ord[i].unitNum); if(pt[ord[i].page].flag==1){ //如果该页标志是1 if (strcmp(ord[i].name, "存") == 0) { pt[ord[i].page].changeFlag = 1; } printf("该页已在主存, 其绝对地址为:"); absolulyAddress(&ord[i],&pt[ord[i].page]); if (p[0] != ord[i].page)//判断当前运行的页面和P数组的开头是否相等。 { n = m-1; for (n; n > 0; n--) { p[n] = p[n-1]; } p[0] = ord[i].page; } } else if(pt[ord[i].page].flag==0) //如果该页标志不是1 { printf("该页不在主存。产生中断信号 *%d\n" ,pt[ord[i].page].pagenum); //中断信号 //更改当前页号的主存块号和标志 pt[ord[i].page].flag = 1; pt[ord[i].page].cachenum = pt[p[m-1]].cachenum; pt[p[m-1]].flag = 0;//更改被替换的页号的标志 printf("%d页被换出,%d页被换入\n\n", p[m-1], ord[i].page); n = m-1; for (n; n > 0; n--) { p[n] = p[n-1]; } p[0] = ord[i].page; i--; } } printf("\n"); //输出P i = 0; for (i;i<m;i++) { printf("p数组的值为: \n"); printf("P[i] = %d\n", p[i]); } printf("\n"); } int main(){ order ord[12] ; //把指令存放到ord数组中 pagetable pt[7]; //把页表存放到pt数组中 readOrder(ord); readPageTable(pt); //第一个 // firstMethod(ord, pt); //第二个 // FIFOMethod(ord, pt); //第三个 LRUMethod(ord, pt); return 0; }
a.txt 如下:
+ 0 70 + 1 50 * 2 15 存 3 21 取 0 56 - 6 40 移位 4 053 + 5 023 存 1 037 取 2 078 + 4 001 存 6 084
b.txt 如下:
0 1 5 0 011 1 1 8 0 012 2 1 9 0 013 3 1 1 0 021 4 0 -1 0 022 5 0 -1 0 023 6 0 -1 0 121
OVER!请大家指出错误和不足。