段页式虚拟存储器

段页式虚拟存储器是段式虚拟存储器和页式虚拟存储器的结合。

     首先,实存被等分成页。在段页式虚拟存储器中,把程序按逻辑结构分段以后,再把每段按照实存的页大小分页,程序按页进行调入和调出操作,但它又可按段实现共享和保护。因此,它可以兼有页式和段式系统的优点。它的缺点是在地址映像过程中需要多次查表,虚拟地址转换成物理地址是通过一个段表和一组页表来进行定位的。段表中的每个表目对应一个段,每个表目有一个指向该段的页表的起始地址(页号)及该段的控制保护信息。由页表指明该段各页在主存中的位置以及是否已装入、已修改等标志。

      如果有多个用户在机器上运行,称为多道程序,多道程序的每一道(每个用户)需要一个基号(用户标志号),可由它指明该道程序的段表起点(存放在基址寄存器中)。一个虚拟地址应包括基号B、段号S、段内逻辑页号P、页内地址D。格式如下:

 

基号B

段号S

段内逻辑页号P

页内地址D

 

      [例3.9]  假设有三道程序,基号用A、B和C表示,其基址寄存器的内容分别为SA、SB和SC。程序A由4个段构成,程序C由3个段构成。段页式虚拟存储系统的逻辑地址到物理地址的变换过程如图3.35所示。

图3.35  段页式虚拟存储器虚实地址变换过程

     在主存中,每道程序都有一张段表,A程序有4段,C程序有3段,每段应有一张页表,段表的每行就表示相应页表的起始位置,而页表内的每行即为相应的物理页号。请说明虚实地址变换过程。

      解:地址变换过程如下:

     (1由存储管理部件根据基号C找到段表基址寄存器表第c个表项,获得程序C的段表基址SC。再根据段号S(=1)找到程序C段表的第S个表项,得到段S的页表起始地址b。

     2)根据段内逻辑页号P(=2)检索页表,得到物理页号(图中物理页号为10)。

     3)物理页号与页内地址偏移量拼接即得物理地址。

      假如计算机系统中只有一个基址寄存器,则基号可不要。多道程序切换时,由操作系统修改基址寄存器内容。

      实际上,上述每个段表和页表的表项中都应设置一个有效位。只有在有效位为1时才按照上述流程操作,否则需中断当前操作先进行建表或调页。



Linux 和 Windows 在 i386 CPU 上执行的时候,虽然既分段也分页,但跟教科书上讲的“段页式”是不同的性质。实际的操作系统往往把分段作为一个摆设,分页做得很细致,段也还是分的,但各个段往往重合到一起(即一个段?),也就是我们平常说的 flat memory model。

分段是必需的,分页是可选的

但是现代操作系统对分段的使用都是敷衍性质。。。。。。。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、 课程设计目的 本课程设计是学生学习完《计算机操作系统》课程后,进行的一次全面的综合训练,通过课程设计,让学生更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。 二、课程设计的内容 1、分页方的地址换算 2、分段方的地址换算 3、段页的地址换算 三、程序运行 1、 分页地址转换: 数据: 逻辑地址:223、页面大小:23 2、 分段地址转换 数据: 逻辑地址段号:223、段内地址:23 3、 段页地址换算 逻辑地址的段号:2、页号:3 四、程序源代码 #include #include int page(int A,int L ); int Segment(int sn,int sl); int SegPagt(int sn,int pn,int pd); typedef struct segtable { int segf[256]; int segl[256]; }segtable; struct segtable st; typedef struct segpagt { int segf[256]; int segl[256]; int ptl[256]; int pt[256]; int pf[256]; int pl; }segpagt; struct segpagt sp; int main() { int code; int pl,pa,sn,sd,pd,pn; //const int ptl ; int temp; do{ printf("----------------地址换算过程----------------------------\n\n"); printf(" 1.分页地址换算\n"); printf(" 2.分段地址换算\n"); printf(" 3.段页地址换算\n"); printf(" 4.结束运行\n\n"); printf("----------------------------------------------------------\n"); printf("请输入您的选择:"); scanf("%d",&code); switch(code) { case 1:{ printf("注意:请演示设定页表长度小于\n"); printf("请输入换算的逻辑地址:\n"); scanf("%d",&pa); printf("页面大小(B):\n"); scanf("%d",&pl); page(pa,pl); }break; case 2:{ printf("请演示设定段表长度小于\n"); printf("请输入逻辑地址的段号:\n"); scanf("%d",&sn); printf("段内地址:\n"); scanf("%d",&sd); Segment(sn,sd); }break; case 3:{ printf("预设定段表长为,页面大小为\n"); printf("请输入逻辑地址的段号:\n"); scanf("%d",&sn); printf("页号:\n"); scanf("%d",&pn); printf("页内地址:\n"); scanf("%d",&pd); SegPagt(sn,pn,pd); }break; case 4:{}break; } }while (code<4); } int page(int A,int L) { int d,P,kd,i; int WD; int PT[256]; for(i=1;iL) printf("页号大于页表长度,越界中断\n\n");//如果页号大于页表长度,输出越界中段 else { printf("页号=逻辑地址/页面大小=%d,页内地址=逻辑地址%页面大小=%d\n",P,d);//输出页号和页内地址 kd=PT[P];//根据页号随机产生快号 printf("根据页号%d得到块号%d\n",P,kd); WD=kd*L+d;//计算物理地址的公 printf("物理地址=块号%d*页面大小%d+页内地址%d\n",kd,L,d);//输出物理地址=块号*页面大小+页内地址 printf("逻辑地址%d换算后的物理地址为%d\n\n",A,WD);//输出物理地址的结果 return (0); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值