《操作系统》实验教学大纲 (一)课程简介 操作系统是计算机科学技术、信息管理、软件工程等专业的一门专业基础课,他的先导 课程有:数据结构、计算机原理、程序设计等课程:操作系统实验课是该门课程的重要组成 部分。 (二)教学目的 通过本实验课的学习,目的使学生能加深操作系统中基本概念的理解,同时对操作系统 中的常用算法的实现具有更直观的理解 (三)使用教材 本课程理论课的教材为:《计算机操作系统》,(修订版),汤子瀛、哲风屏、汤小丹编著, 西安电子科技出版社,2002.8 (四)考核方式 本实验的考核以所提交的上机作业为考核依据,实验课程的成绩不单独计算,它占总成 绩的20%。 (五)实验课内容 实验编号01201001 实验名称用汇编语言写出P、V操作原语 实验內容编程 实验类型设计 实验学时2学时 实验目的掌握P、V操作的设计方法 实验要求必修 实验编号01201002 实验名称用高级语言写出基于消息传递的进程通讯方法 实验内容编程 实验类型设计 实验学时2学时 实验目的掌握消息传递和同步 实验要求必修 实验编号01201003 实验名称用高级语言写出银行家算法 实验內容编程 实验类型设计 实验学时2学时 实验目的掌握避免死锁的方法 实验要求必修 实验编号01201004 实验名称用高级语言写出按最先适应算法的存储器管理程序 实验内容编程 实验类型设计
《操作系统》实验教学大纲 (一) 课程简介 操作系统是计算机科学技术、信息管理、软件工程等专业的一门专业基础课,他的先导 课程有:数据结构、计算机原理、程序设计等课程;操作系统实验课是该门课程的重要组成 部分。 (二) 教学目的 通过本实验课的学习,目的使学生能加深操作系统中基本概念的理解,同时对操作系统 中的常用算法的实现具有更直观的理解。 (三) 使用教材 本课程理论课的教材为:《计算机操作系统》,(修订版),汤子瀛、哲风屏、汤小丹编著, 西安电子科技出版社,2002.8 (四) 考核方式 本实验的考核以所提交的上机作业为考核依据,实验课程的成绩不单独计算,它占总成 绩的 20%。 (五) 实验课内容 实验编号 01201001 实验名称 用汇编语言写出 P、V 操作原语 实验内容 编程 实验类型 设计 实验学时 2 学时 实验目的 掌握 P、V 操作的设计方法 实验要求 必修 实验编号 01201002 实验名称 用高级语言写出基于消息传递的进程通讯方法 实验内容 编程 实验类型 设计 实验学时 2 学时 实验目的 掌握消息传递和同步 实验要求 必修 实验编号 01201003 实验名称 用高级语言写出银行家算法 实验内容 编程 实验类型 设计 实验学时 2 学时 实验目的 掌握避免死锁的方法 实验要求 必修 实验编号 01201004 实验名称 用高级语言写出按最先适应算法的存储器管理程序 实验内容 编程 实验类型 设计
实验学时2学时 实验目的掌握分区管理的实现方法 实验要求必修 实验编号01201005 实验名称用高级语言写出改进的LRU算法的程序实现 实验内容编程 实验类型设计 实验学时2学时 实验目的掌握一种淘汰算法 实验要求必修 实验编号01201006 实验名称用高级语言写出事务实现的模拟程序 实验内容编程 实验类型设计 实验学时2学时 实验目的掌握RED()和UN0()过程的设计 实验要求必修 说明:本课程的所有实验约需要16~18个学时,实验全部在微机上实现,所以上表中未列 出实验所需的设备:上机时间从第6周到第16周 早上看了水晶龙的一个undo的例子,其中虽然有一些 command模式的思想,但是用的好像不够正宗。其 实用 command模式实现undo和redo应该还是比较容易的,做个例子练练手吧: test command var action Stack=U∥操作栈
实验学时 2 学时 实验目的 掌握分区管理的实现方法 实验要求 必修 实验编号 01201005 实验名称 用高级语言写出改进的 LRU 算法的程序实现 实验内容 编程 实验类型 设计 实验学时 2 学时 实验目的 掌握一种淘汰算法 实验要求 必修 实验编号 01201006 实验名称 用高级语言写出事务实现的模拟程序 实验内容 编程 实验类型 设计 实验学时 2 学时 实验目的 掌握 REDO()和 UNDO()过程的设计 实验要求 必修 说明:本课程的所有实验约需要 16~18 个学时,实验全部在微机上实现,所以上表中未列 出实验所需的设备;上机时间从第 6 周到第 16 周 早上看了水晶龙的一个 undo 的例子,其中虽然有一些 command 模式的思想,但是用的好像不够正宗。其 实用 command 模式实现 undo 和 redo 应该还是比较容易的,做个例子练练手吧: test command <!-- var actionStack = [];//操作栈
var actionIndex=0操作栈中当前操作的指针 command对象基类 function Base Actionot BaseAction prototype exec=function(( action StacklactionIndex++]=this: action Stack length=actionIndex BaseAction prototype undo=function( alert(“此操作未定义相应的undo操作 Base Action. prototype redo=functiond alert(“此操作未定义相应的redo操作") ∥--move操作的 com mand对象 function Move Action(elml is oldX= elm. oldX this oldY= elm.oldY this newX= elm .newX this newY= elm. newY this source Element =el this status ="done Move Action. prototype= new BaseAction0: Move Action. prototype undo=functional if (this status I="done )return
var actionIndex = 0;//操作栈中当前操作的指针 //----------------------- command 对象基类 ------------------------------ function BaseAction(){ } BaseAction.prototype.exec=function(){ actionStack[actionIndex++] = this; actionStack.length = actionIndex; } BaseAction.prototype.undo=function(){ alert("此操作未定义相应的 undo 操作"); } BaseAction.prototype.redo=function(){ alert("此操作未定义相应的 redo 操作"); } //----------------------- move 操作的 command 对象 ------------------------------ function MoveAction(elm){ this.oldX = elm.oldX; this.oldY = elm.oldY; this.newX = elm.newX; this.newY = elm.newY; this.sourceElement = elm; this.status = "done"; } MoveAction.prototype = new BaseAction(); MoveAction.prototype.undo=function(){ if (this.status != "done") return;
this source Element style left= this. oldX this source Element style. top= this oldY; this status ="undone Move Action. prototype redo=function if this status l="undone")retum this source Element style left= this newX this source Element style top=this newY this status =done change操作的 com mand对象 function ChangeAction(elm) this source Element=elm lis oldvalue elm defaultvalue lis. newvalue =elm value elm defaultvalue =elm value this status ="done ChangeAction prototype= new BaseActiono ChangeAction prototype undo = function if(this status I="done )return lis source Element value= this source Element defaultvalue this oldValue this status ="undone ChangeAction prototype redo =function( if(this status l="undone")return s source Element value this. new Value
this.sourceElement.style.left = this.oldX; this.sourceElement.style.top = this.oldY; this.status = "undone"; } MoveAction.prototype.redo=function(){ if (this.status != "undone") return; this.sourceElement.style.left = this.newX; this.sourceElement.style.top = this.newY; this.status = "done"; } //----------------------- change 操作的 command 对象 ------------------------------ function ChangeAction(elm){ this.sourceElement = elm; this.oldValue = elm.defaultValue; this.newValue = elm.value; elm.defaultValue = elm.value; this.status = "done"; } ChangeAction.prototype = new BaseAction(); ChangeAction.prototype.undo = function(){ if (this.status != "done") return; this.sourceElement.value = this.sourceElement.defaultValue = this.oldValue; this.status = "undone"; } ChangeAction.prototype.redo = function(){ if (this.status != "undone") return; this.sourceElement.value = this.newValue;
this status =done 全局函数 function undoot f(actionIndex>OX action Stack[--actionIndex] undo function redoot if (actionIndex<action Stack length) action StacklactionIndex++] redo: function checkMouse MoveD if (window. active Element) var elm window active Element elm style left=event. X-elm. inner elm. style. top= event. y-elm inner function releaseMouseO if (window. active Element) active ElementnewX=event x-active Element inner activeElement new Y=event y-activeElement inner ew Move Action(active Element). execo
this.status = "done"; } //--------------------- 全局函数 ---------------------------- function undo(){ if (actionIndex>0){ actionStack[--actionIndex].undo(); } } function redo(){ if (actionIndex<actionStack.length){ actionStack[actionIndex++].redo(); } } function checkMouseMove(){ if (window.activeElement){ var elm = window.activeElement; elm.style.left = event.x-elm.innerX; elm.style.top = event.y-elm.innerY; } } function releaseMouse(){ if (window.activeElement){ activeElement.newX = event.x-activeElement.innerX; activeElement.newY = event.y-activeElement.innerY; new MoveAction(activeElement).exec();
window. active Element= null function drago( if (event. button=2)return ar elm eventsrcElement window active Element=elm elm . oldX=elm. offsetLeft elm oldY =elm. offsetTop elm innerX=event.x-elm .oldX. elm. inner'Y= event y-elmoldY function change ValueD new ChangeAction(event. srcElement). execO ∥>
window.activeElement = null; } } function drag(){ if (event.button!=2) return; var elm = event.srcElement; window.activeElement = elm; elm.oldX = elm.offsetLeft; elm.oldY = elm.offsetTop; elm.innerX = event.x - elm.oldX; elm.innerY = event.y - elm.oldY; } function changeValue(){ new ChangeAction(event.srcElement).exec(); } //-->
input value="drag me"onmousedown="drago"onchange="changeValueo style="position: absolute; left: 550; color violet> 用鼠标右键拖动输入框,或者直接修改输入框的内容,可以一一undo再redo。 看来效果还不错。秋水说有bug,不过我没有重现出来呢? 汤子瀛计算机操作系统(西电)答案-第五章 1.可采用哪几种方式将程序装入内存?它们分别适用于何种场合? a.首先由编译程序将用户源代码编译成若干目标模块,再由链接程序将编译后形成的 目标模块和所需的 库函数链接在一起,组成一个装入模块,再由装入程序将装入模块装入内存; b.装入模块的方式有:绝对装入方式,可重定位方式和动态运行时装入方式; C.绝对装入方式适用于单道程序环境下 d.可重定位方式适用于多道程序环境下 e.动态运行时装入方式也适用于多道程序环境下 2.何谓静态链接及装入时动态链接和运行时的动态链接? a.静态链接是指事先进行链接形成一个完整的装入模块,以后不再拆开的链接方- 式 b.装入时动态链接是指目标模块在装入内存时,边装入边链接的链接方式 C.运行时的动态链接是将某些目标模块的链接推迟到执行时才进行 3.在进行程序链接时,应完成哪些工作? a.对相对地址进行修改; b.变换外部调用符号 4.在动态分区分配方式中,可利用哪些分区分配算法? a.首次适应算法 b.循环首次适应算法; C.最佳适应算法 5.在动态分区分配方式中,应如何将各空闲分区链接成空闲分区链? 应在每个分区的起始地址部分,设置一些用于控制分区分配的信息,以及用于链接各 分区的前向指针; 在分区尾部则设置一后向指针,通过前,后向指针将所有的分区链接成一个双向链. 6.为什么要引入动态重定位?如何实现?
用鼠标右键拖动输入框,或者直接修改输入框的内容,可以一一 undo 再 redo 。 看来效果还不错。秋水说有 bug,不过我没有重现出来呢? -- 汤子瀛计算机操作系统(西电)答案--第五章 1. 可采用哪几种方式将程序装入内存?它们分别适用于何种场合? a. 首先由编译程序将用户源代码编译成若干目标模块,再由链接程序将编译后形成的 目标模块和所需的 ---库函数链接在一起,组成一个装入模块,再由装入程序将装入模块装入内存; b. 装入模块的方式有: 绝对装入方式,可重定位方式和动态运行时装入方式; c. 绝对装入方式适用于单道程序环境下; d. 可重定位方式适用于多道程序环境下; e. 动态运行时装入方式也适用于多道程序环境下. 2. 何谓静态链接及装入时动态链接和运行时的动态链接? a. 静态链接是指事先进行链接形成一个完整的装入模块,以后不再拆开的链接方--- 式; b. 装入时动态链接是指目标模块在装入内存时,边装入边链接的链接方式; c. 运行时的动态链接是将某些目标模块的链接推迟到执行时才进行. 3. 在进行程序链接时,应完成哪些工作? a. 对相对地址进行修改; b. 变换外部调用符号. 4. 在动态分区分配方式中,可利用哪些分区分配算法? a. 首次适应算法; b. 循环首次适应算法; c. 最佳适应算法. 5. 在动态分区分配方式中,应如何将各空闲分区链接成空闲分区链? 应在每个分区的起始地址部分,设置一些用于控制分区分配的信息,以及用于链接各 分区的前向指针; 在分区尾部则设置一后向指针,通过前,后向指针将所有的分区链接成一个双向链. 6. 为什么要引入动态重定位?如何实现?
a.为了在程序执行过程中,每当访问指令或数据时,将要访问的程序或数据的逻辑地 址转换成物理地 址,引入了动态重定位 b.可在系统中增加一个重定位寄存器,用它来装入(存放)程序在内存中的起始地址, 程序在执行时,真 正访问的内存地址是相对地址与重定位寄存器中的地址相加而形成的从而实现动 态重定位 7.试用类 Pascal语言来描述首次适应算法进行内存分配的过程 (略) 8.在采用首次适应算法回收内存时,可能出现哪几种情况?应怎样处理这些情况? a.回收区与插入点的前一个分区相邻接,此时可将回收区与插入点的前一分区合并, 不再为回收分区 --分配新表项,而只修改前邻接分区的大小; b.回收分区与插入点的后一分区相邻接,此时合并两区,然后用回收区的首址作为新 空闲区的首址,大 小为两者之和; C.回收区同时与插入点的前后两个分区邻接,此时将三个分区合并,使用前邻接分区 的首址,大小为 三区之和,取消后邻接分区的表项 d.回收区没有邻接空闲分区,则应为回收区单独建立一个新表项,填写回收区的首址 和大小,并根据 其首址,插入到空闲链中的适当位置 9.在系统中引入对换后带有哪些好处? 能将内存中暂时不运行的进程或暂时不用的程序和数据,换到外存上,以腾出足够的 内存空间,把已 具备运行条件的进程或进程所需的程序和数据换入内存,从而大大地提高了内存的利 用率 10为实现对换,系统应具备哪几方面功能? a.对对换空间的管理; b.进程的换出 C.进程的换入 11在以进程为单位进行对换时,每次是否都将整个进程换出?为什么? a.以进程为单位进行对换时,每次都将整个进程换出 b.目的为了解决内存紧张的问题,提高内存的利用率 12为实现分页存储管理,需要哪些硬件支持?你认为以Inte8086MC68000, Inte|80286为芯片的微机,是否适合于实现分页管理? (有待讨论)
a. 为了在程序执行过程中,每当访问指令或数据时,将要访问的程序或数据的逻辑地 址转换成物理地 ---址,引入了动态重定位. b. 可在系统中增加一个重定位寄存器,用它来装入(存放)程序在内存中的起始地址, 程序在执行时,真 ---正访问的内存地址是相对地址与重定位寄存器中的地址相加而形成的,从而实现动 态重定位. 7. 试用类 Pascal 语言来描述首次适应算法进行内存分配的过程. (略) 8. 在采用首次适应算法回收内存时,可能出现哪几种情况?应怎样处理这些情况? a. 回收区与插入点的前一个分区相邻接,此时可将回收区与插入点的前一分区合并, 不再为回收分区 ---分配新表项,而只修改前邻接分区的大小; b. 回收分区与插入点的后一分区相邻接,此时合并两区,然后用回收区的首址作为新 空闲区的首址,大 ---小为两者之和; c. 回收区同时与插入点的前后两个分区邻接,此时将三个分区合并,使用前邻接分区 的首址,大小为 ---三区之和,取消后邻接分区的表项; d. 回收区没有邻接空闲分区,则应为回收区单独建立一个新表项,填写回收区的首址 和大小,并根据 ---其首址,插入到空闲链中的适当位置. 9. 在系统中引入对换后带有哪些好处? 能将内存中暂时不运行的进程或暂时不用的程序和数据,换到外存上,以腾出足够的 内存空间,把已 具备运行条件的进程或进程所需的程序和数据换入内存,从而大大地提高了内存的利 用率. 10 为实现对换,系统应具备哪几方面功能? a. 对对换空间的管理; b. 进程的换出; c. 进程的换入. 11 在以进程为单位进行对换时,每次是否都将整个进程换出?为什么? a. 以进程为单位进行对换时,每次都将整个进程换出; b. 目的为了解决内存紧张的问题,提高内存的利用率. 12 为实现分页存储管理,需要哪些硬件支持?你认为以 Intel 8086,MC68000, Intel 80286 为芯片的微机,是否适合于实现分页管理? (有待讨论)
13请较详细地说明,引入分页存储管理(估计印错了,是分段存储管理)是为了满足 用户哪几方面的需要? a.方便了编程 b.实现了分段共享; C.实现了分段保护; d.实现了动态链接; e.实现了动态增长 14在具有快表的段页式存储管理方式中,如何实现地址变换? 首先,必须配置一段表寄存器,在其中存放段表始址和段长T,进行地址变换时,先 利用段号S,与段长TL 进行比较,若S=TL,表示段号太大,访问越界,产生越界 中断信号)于是利用段表 始址和段号来求出该段对应的段表项在段表中的位置,从中求出该段的页表始址,并 利用逻辑地址中的段 内页号P来获得对应页的页表项位置,从中读出该页所在的物理块号b,再用块号b 和页内地址构成物理地址 15为什么说分段系统较之分页系统更易于实现信息共享和保护? a.对于分页系统,每个页面是分散存储的,为了实现信息共享和保护,则页面之间需 要一一对应起来,为此 需要建立大量的页表项; b.而对于分段系统,每个段都从0开始编址,并采用一段连续的地址空间,这样在 实现共享和保护时,只需 为所要共享和保护的程序设置一个段表项,将其中的基址与内存地址一一对应起来 即可 16分页和分段有何区别 a.分页和分段都采用离散分配的方式,且都要通过地址映射机构来实现地址变换,这 是它们的共同点 b.对于它们的不同点有三,第一,从功能上看,页是信息的物理单位,分页是为实现 离散分配方式,以消减 --内存的外零头,提高内存的利用率,即满足系统管理的需要,而不是用户的需要 而段是信息的逻辑单位 它含有一组其意义相对完整的信息,目的是为了能更好地满足用户的需要 C.页的大小固定且由系统确定,而段的长度却不固定,决定于用户所编写的程序 d.分页的作业地址空间是一维的,而分段的作业地址空间是二维的 17试全面比较连续分配和离散分配方式 a.连续分配是指为一个用户程序分配一个连续的地址空间,包括单一连续分配方式和 分区式分配方式,前者 将内存分为系统区和用户区,系统区供操作系统使用,用户区供用户使用,是最简 单的一种存储方式, -但只能用于单用户单任务的操作系统中;分区式分配方式分为固定分区和动态分
13 请较详细地说明,引入分页存储管理(估计印错了,是分段存储管理)是为了满足 用户哪几方面的需要? a. 方便了编程; b. 实现了分段共享; c. 实现了分段保护; d. 实现了动态链接; e. 实现了动态增长. 14 在具有快表的段页式存储管理方式中,如何实现地址变换? 首先,必须配置一段表寄存器,在其中存放段表始址和段长 TL. 进行地址变换时,先 利用段号 S,与段长 TL 进行比较,若 S=TL,表示段号太大,访问越界,产生越界 中断信号)于是利用段表 始址和段号来求出该段对应的段表项在段表中的位置,从中求出该段的页表始址,并 利用逻辑地址中的段 内页号 P 来获得对应页的页表项位置,从中读出该页所在的物理块号 b,再用块号 b 和页内地址构成物理地址. 15 为什么说分段系统较之分页系统更易于实现信息共享和保护? a. 对于分页系统,每个页面是分散存储的,为了实现信息共享和保护,则页面之间需 要一一对应起来,为此 ---需要建立大量的页表项; b. 而对于分段系统,每个段都从 0 开始编址,并采用一段连续的地址空间,这样在 实现共享和保护时,只需 ---为所要共享和保护的程序设置一个段表项,将其中的基址与内存地址一一对应起来 即可. 16 分页和分段有何区别? a. 分页和分段都采用离散分配的方式,且都要通过地址映射机构来实现地址变换,这 是它们的共同点; b. 对于它们的不同点有三,第一,从功能上看,页是信息的物理单位,分页是为实现 离散分配方式,以消减 ---内存的外零头,提高内存的利用率,即满足系统管理的需要,而不是用户的需要; 而段是信息的逻辑单位, ---它含有一组其意义相对完整的信息,目的是为了能更好地满足用户的需要; c. 页的大小固定且由系统确定,而段的长度却不固定,决定于用户所编写的程序; d. 分页的作业地址空间是一维的,而分段的作业地址空间是二维的. 17 试全面比较连续分配和离散分配方式. a. 连续分配是指为一个用户程序分配一个连续的地址空间,包括单一连续分配方式和 分区式分配方式,前者 ---将内存分为系统区和用户区,系统区供操作系统使用,用户区供用户使用,是最简 单的一种存储方式, ---但只能用于单用户单任务的操作系统中;分区式分配方式分为固定分区和动态分
区,固定分区是最简单的 多道程序的存储管理方式,由于每个分区的大小固定,必然会造成存储空间的浪费 动态分区是根据进程 的实际需要,动态地为之分配连续的内存空间,常用三种分配算法:首次适应算法 FF,该法容易留下许多 难以利用的小空闲分区,加大査找开销:循环首次适应算法,该算法能使内存中的 空闲分区分布均匀,但 会致使缺少大的空闲分区;最佳适应算法,该算法也易留下许多难以利用的小空闲 区 b.离散分配方式基于将一个进程直接分散地分配到许多不相邻的分区中的思想,分为 分页式存储管理,分段 存储管理和段页式存储管理.分页式存储管理旨在提高内存利用率,满足系统管理 的需要,分段式存储管 理则旨在满足用户(程序员)的需要,在实现共享和保护方面优于分页式存储管理 而段页式存储管理则是 --将两者结合起来,取长补短,即具有分段系统便于实现,可共享,易于保护,可动 态链接等优点,又能像 分页系统那样很好的解决外部碎片的问题,以及为各个分段可离散分配内存等问 题,显然是一种比较有效 的存储管理方式 C.综上可见,连续分配方式和离散分配方式各有各自的特点,应根据实际情况加以改 进和利用. ※来源:考研论坛 bbs. kaoyan 作者:tply 发布时间:2004-1-908:18:00 汤子瀛计算机操作系统(西电)答案-第六章 1.在请求分页系统中,其页表项中包含那些数据项?它们的作用是什么? a.在请求分页系统中,其页表项中包含的数据项有页号,物理块号,状态位P,访问 字段A,修改位M和 外存地址 b.其中状态位P指示该页是否调入内存,供程序访问时参考; C.访问字段A用于记录本页在一段时间内被访问的次数,或最近已有多长时间未被 访问,提供给置换算法 --选择换出页面时参考; d.修改位M表示该页在调入内存后是否被修改过 e.外存地址用于指出该页在外存上的地址,通常是物理块号,供调入该页时使用. 2.一个计算机系统的虚拟存储器,其最大容量和实际容量分别由什么决定? a.最大容量由内存和外存之和决定; b.实际容量由内存决定
区,固定分区是最简单的 ---多道程序的存储管理方式,由于每个分区的大小固定,必然会造成存储空间的浪费; 动态分区是根据进程 ---的实际需要,动态地为之分配连续的内存空间,常用三种分配算法: 首次适应算法 FF,该法容易留下许多 ---难以利用的小空闲分区,加大查找开销;循环首次适应算法,该算法能使内存中的 空闲分区分布均匀,但 ---会致使缺少大的空闲分区;最佳适应算法,该算法也易留下许多难以利用的小空闲 区; b. 离散分配方式基于将一个进程直接分散地分配到许多不相邻的分区中的思想,分为 分页式存储管理,分段 ---存储管理和段页式存储管理. 分页式存储管理旨在提高内存利用率,满足系统管理 的需要,分段式存储管 ---理则旨在满足用户(程序员)的需要,在实现共享和保护方面优于分页式存储管理, 而段页式存储管理则是 ---将两者结合起来,取长补短,即具有分段系统便于实现,可共享,易于保护,可动 态链接等优点,又能像 ---分页系统那样很好的解决外部碎片的问题,以及为各个分段可离散分配内存等问 题,显然是一种比较有效 ---的存储管理方式; c. 综上可见,连续分配方式和离散分配方式各有各自的特点,应根据实际情况加以改 进和利用. ※ 来源:考研论坛 bbs.kaoyan. -- 作者:ltply -- 发布时间:2004-1-9 08:18:00 -- 汤子瀛计算机操作系统(西电)答案--第六章 1. 在请求分页系统中,其页表项中包含那些数据项? 它们的作用是什么? a. 在请求分页系统中,其页表项中包含的数据项有页号,物理块号,状态位 P,访问 字段 A,修改位 M 和 ---外存地址; b. 其中状态位 P 指示该页是否调入内存,供程序访问时参考; c. 访问字段 A 用于记录本页在一段时间内被访问的次数,或最近已有多长时间未被 访问,提供给置换算法 ---选择换出页面时参考; d. 修改位 M 表示该页在调入内存后是否被修改过; e. 外存地址用于指出该页在外存上的地址,通常是物理块号,供调入该页时使用. 2. 一个计算机系统的虚拟存储器,其最大容量和实际容量分别由什么决定? a. 最大容量由内存和外存之和决定; b. 实际容量由内存决定