课程设计任务书及成绩评定课题名称基本分页存储管理系统的设计Ⅰ、题目的目的和要求:巩固和加深对操作系统(OS)原理的理解,初步掌握操作系统组成模块和应用接口的使用方法,提高进行工程设计和系统分析的能力;通过选做上面的课题,实现OS最基本模块的管理功能,重点放在数据结构设计、文档规范化和程序设计风格。
Ⅱ、设计进度及完成情况Ⅲ、主要参考文献及资料[1] 汤子赢等. 计算机操作系统(第二版).西安电子科技大学出版社,2006.8[2] 冯耀霖等. 操作系统,西安电子科技大学出版社.1992[3] 谭耀铭. 操作系统.中国人民大学出版社,2003.4[4] 任爱华操作系统实用教程清华大学出版社,2001[5] 张尧学史美林计算机操作系统教程(第2版)清华大学出版社2000Ⅳ、成绩评定:设计成绩:(教师填写)指导老师:(签字)二○○八年六月二十七日目录第一章概述 (1)第二章系统分析 (2)第三章系统设计 (3)第四章程序设计流程图或N-S图 (5)第五章源程序清单 (8)第六章调试过程中的问题及系统测试情况 (14)第七章结束语 (16)第一章概述课程设计是实践性教学中的一个重要环节,它以某一课程为基础,可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。
课程设计是让同学们对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。
《计算机操作系统》一门重要的专业课,是开发操作系统和软件系统的理论和应用基础。
存储器是计算机系统的重要组成部分。
近几年,虽然存储器的容量一直在不断的扩大,价格也越来越便宜,但是仍然不能满足现代软件发展的需要。
因此存储器仍是一种宝贵的资源。
因此尽可能的方便用户和提高主存储器的使用效率,使主存储器在成本、速度和规模之间获得较好的权衡是存储器管理的主要任务。
存储器管理应具有内存分配、内存保护、地址映射和内存扩充等功能。
本设计的目的是熟悉存贮器管理系统的设计方法;加深对所学基本分页存储管理方案的了解;设计地址变换机构,并将变换后的结果显示出来。
模拟环境应尽量接近真实。
此次设计利用了大量数据结构中关于链表的相关知识,对以前所学的数据结构相关内容进行了回顾,从而掌握的更加深刻。
另外,对存储器的结构和工作过程也有了直观而深刻的理解。
语言方面,本次课程设计运用了C++语言。
原因是通过分析认为只有C++和C语言比较合适,而C++在结构上更加清晰,也比较容易表达,并且代码较少。
通过代码编写和结构表达,对C++的内容有了更进一步的掌握。
总之,对所学的数据结构和C++知识进行了很好的回顾和掌握,收获很大。
第二章系统分析本设计的目的是熟悉存贮器管理系统的设计方法;加深对所学各种存贮器管理方案的了解;要求采用一些常用的存贮器分配算法,设计一个存贮器管理系统模拟系统并调试运行。
模拟环境应尽量接近真实。
因此根据设计要求,本存储器管理系统利用最佳适应算法和首次适应算法实现了一定大小的分区分配和分区回收,并以次来模拟存储器管理。
本系统模拟实现可变分区管理,存储管理主要是对存储空间的分配和回收,当有用户申请空间时,进行分配,空间不用了,及时回收,以免造成游离空间,使得该空间再也无法使用,可变分区管理的分配和回收功能类似于visual c++的reclaim()和free()的功能,分区收回算法,才用首次使用算法和最佳适应算法。
在多道程序环境下,要使程序运行,必须先为之创建进程。
而创建进程的第一步是将程序和数据装入内存。
存储器实现的功能主要是内存分配等功能,本模拟系统所要实现的就是将进程的程序和数据装入内存(物理块)。
具体需要实现的功能如下:1、退出,输入0然后按任意键退出;2、分配主存,输入作业名和作业所需长度,回到主菜单;3、回收主存,选择后输入要回收的作业名,有则显示回收,无则显示无该作业;4、显示主存,能够显示分配的页面的状态信息,包括地址范围和读入的内存物理块号(未读入与读入的区别显示),页面是否在主存中。
第三章系统设计3.1 数据结构的设计#define n 10 /*假定系统允许的最大作业数为n,假定模拟实验中n值为10*/#define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/3.1.1已分配区表的设计struct{float address; /*已分配分区起始地址*/float length; /*已分配分区长度,单位为字节*/int flag; /*已分配区表登记栏标志,用"0"表示空栏目*/}used_table[n]; /*已分配区表*/3.1.2 空闲区表的设计struct{float address; /*空闲区起始地址*/float length; /*空闲区长度,单位为字节*/int flag; /*空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配*/}free_table[m]; /*空闲区表*/3.2 存储器分配算法设计本次设计采用最佳适应分配算法:allocate(char J,float xk)分配分区给用户,在这个过程中,每当分配一个分区给用户时,可能造成空闲区表和已分配区表。
分配时从空闲区表中找到一块可以容纳要分配的空间的最小空闲区。
然后分配,空闲分区被分配时,如果分配后剩余的空间小于minisize,则将该空闲分区全部分配,若大于minisize,则切割分配。
分配时修改相应的空闲区表和已分配区表。
如果没有找到可以容纳要分配的空间的空闲区就返回“无可用空闲区”信息。
3.4存储器回收算法设计最佳适应策略的结点是按照空闲区大小从小到大排列的,可分4种情况:(1)上邻空闲区,下邻空闲区,三项合并;(2)上邻空闲区,下邻非空闲区,与上邻合并;(3)上邻非空闲区,下邻为空闲区,与下邻合并;(4)上下邻均为非空闲区,回收区域直接填入。
3.4 主函数模块的设计首先提供一个功能菜单,接受用户的输入;然后根据用户的输入,分别提供相应的功能,功能有以下几个:0-退出1-分配主存2-回收主存3-显示主存。
用户输入数字后执行相应模块。
第四章程序设计流程图或N-S图4.1主程序流程图:4.2分配函数流程图:4.3回收函数流程图:第五章源程序清单#include<stdio.h>#include <dos.h>#include<stdlib.h>#include<conio.h>#include<iostream.h>#define n 10 /*假定系统允许的最大作业数为n,假定模拟实验中n值为10*/#define m 10 /*假定系统允许的空闲区表最大为m,假定模拟实验中m值为10*/#define minisize 100 /*空闲分区被分配时,如果分配后剩余的空间小于minisize,则将该空闲分区全部分配,若大于minisize,则切割分配*/struct{float address; /*已分配分区起始地址*/float length; /*已分配分区长度,单位为字节*/int flag; /*已分配区表登记栏标志,用"0"表示空栏目*/}used_table[n]; /*已分配区表*/struct{float address; /*空闲区起始地址*/float length; /*空闲区长度,单位为字节*/int flag; /*空闲区表登记栏标志,用"0"表示空栏目,用"1"表示未分配*/}free_table[m]; /*空闲区表*/void allocate(char J,float xk) /*给J作业,采用最佳分配算法分配xk大小的空间*/{int i,k;float ad;k=-1;for(i=0;i<m;i++) /*寻找空间大于xk的最小空闲区登记项k*/if(free_table[i].length>=xk&&free_table[i].flag==1)if(k==-1||free_table[i].length<free_table[k].length)k=i;if(k==-1)/*未找到可用空闲区,返回*/{printf("无可用空闲区\n");return;}/*找到可用空闲区,开始分配:若空闲区大小与要求分配的空间差小于minisize大小,则空闲区全部分配;若空闲区大小与要求分配的空间差大于minisize大小,则从空闲区划出一部分分配*/if(free_table[k].length-xk<=minisize){free_table[k].flag=0;ad=free_table[k].address;xk=free_table[k].length;}else{free_table[k].length=free_table[k].length-xk;ad=free_table[k].address+free_table[k].length;}/*修改已分配区表*/i=0;while(used_table[i].flag!=0&&i<n) /*寻找空表目*/i++;if(i>=n) /*无表目可填写已分配分区*/{printf("无表目填写已分分区,错误\n");/*修正空闲区表*/if(free_table[k].flag==0)/*前面找到的是整个空闲分区*/free_table[k].flag=1;else{/*前面找到的是某个空闲分区的一部分*/free_table[k].length=free_table[k].length+xk;return;}}else{/*修改已分配表*/used_table[i].address=ad;used_table[i].length=xk;used_table[i].flag=J;}return;}/*主存分配函数结束*/void reclaim(char J)/*回收作业名为J的作业所占主存空间*/{int i,k,j,s,t;float S,L;/*寻找已分配表中对应登记项*/s=0;while((used_table[s].flag!=J||used_table[s].flag==0)&&s<n)s++;if(s>=n)/*在已分配表中找不到名字为J的作业*/{printf("找不到该作业\n");return;}/*修改已分配表*/used_table[s].flag=0;/*取得归还分区的起始地址S和长度L*/S=used_table[s].address;L=used_table[s].length;j=-1;k=-1;i=0;/*寻找回收分区的空闲上下邻,上邻表目k,下邻表目j*/ while(i<m&&(j==-1||k==-1)){if(free_table[i].flag==1){if(free_table[i].address+free_table[i].length==S)k=i;/*找到上邻*/ if(free_table[i].address==S+L)j=i;/*找到下邻*/}i++;}if(k!=-1)if(j!=-1)/* 上邻空闲区,下邻空闲区,三项合并*/{free_table[k].length=free_table[j].length+free_table[k].length+L; free_table[j].flag=0;}else/*上邻空闲区,下邻非空闲区,与上邻合并*/free_table[k].length=free_table[k].length+L;elseif(j!=-1)/*上邻非空闲区,下邻为空闲区,与下邻合并*/{free_table[j].address=S;free_table[j].length=free_table[j].length+L;}else/*上下邻均为非空闲区,回收区域直接填入*/{/*在空闲区表中寻找空栏目*/t=0;while(free_table[t].flag==1&&t<m)t++;if(t>=m)/*空闲区表满,回收空间失败,将已分配表复原*/{printf("主存空闲表没有空间,回收空间失败\n");used_table[s].flag=J;return;}free_table[t].address=S;free_table[t].length=L;free_table[t].flag=1;}return;}/*主存回收函数结束*/int main( ){int i,a;float xk;char J;/*空闲分区表初始化:*/free_table[0].address=10240; /*起始地址假定为10240*/free_table[0].length=10240; /*长度假定为10240,即10k*/free_table[0].flag=1; /*初始空闲区为一个整体空闲区*/for(i=1;i<m;i++)free_table[i].flag=0; /*其余空闲分区表项未被使用*//*已分配表初始化:*/for(i=0;i<n;i++)used_table[i].flag=0; /*初始时均未分配*/while(1){printf("选择功能项:\n0-退出\n1-分配主存\n2-回收主存\n3-显示主存)\n"); printf("选择功项(0-3):\n");scanf("%d",&a);switch(a){case 0: exit(0); /*a=0程序结束*/case 1: /*a=1分配主存空间*/printf("输入作业名J和作业所需长度xk: ");scanf("%*c%c%f",&J,&xk);allocate(J,xk); /*分配主存空间*/break;case 2: /*a=2回收主存空间*/printf("输入要回收分区的作业名");scanf("%*c%c",&J);reclaim(J); /*回收主存空间*/break;case 3: /*a=3显示主存情况*//*输出空闲区表和已分配表的内容*/printf("输出空闲区表:\n起始地址分区长度标志\n");for(i=0;i<m;i++)printf("%6.0f%9.0f%6d\n",free_table[i].address,free_table[i].length, free_table[i].flag);printf(" 按任意键,输出已分配区表\n");getch();printf(" 输出已分配区表:\n起始地址分区长度标志\n");for(i=0;i<n;i++)if(used_table[i].flag!=0)printf("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].length,used_table[i].flag);elseprintf("%6.0f%9.0f%6d\n",used_table[i].address,used_table[i].length,used_table[i].flag);break;default:printf("没有该选项\n");}/*case*/}/*while*/return 1;}/*主函数结束*/第六章调试过程中的问题及系统测试情况系统测试情况:6.1功能主菜单:6.2选择功能1,输入作业名和长度:6.3选择功能3,显示系统主存空间表,按任意键显示已分配区表:6.4选择功能2,回收以输入的作业:。