与分页最大的区别:离散分配时所分配地址空间的基本单位不同
分段
进程的地址空间:按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名(在低级语言中,程序员使用段名来编程),每段从0开始编址
内存分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻
按照逻辑功能模块划分,用户编程更方便,程序的可读性更高
分段系统的逻辑地址结构由段号(段名)和段内地址(段内偏移量)组成
段表:每个段表项包含段长、段基址
各个段表项的长度相同
段号可以是隐藏的,不占存储空间
段表寄存器:段表起始地址和段表长度
访问过程
- 根据逻辑地址得到段号S、段内地址W
- 判断段号是否发生越界。若S≥M,则产生越界中断,否则继续执行
- 查询段表,找到对应的段表项,段表项的存放地址为段表起始地址F+S*段表项长度
- 检查段内地址是否超过段长C,若W≥C,则产生越界中断,否则继续执行
- 断基址b+段内地址W得到物理地址E
- 访问目标内存单元
分页和分段的对比
页是信息的物理单位,分页的目的是为了实现离散分配,提高内存利用率,分页仅仅是操作系统管理上的需要,是系统行为,对用户是不可见的
段是信息的逻辑单位,分段的目的是更好地满足用户需求,一个段通常包含着一组属于一个逻辑模块的信息。分段对用户是可见的,用户编程时需要显式给出段名
页的大小固定,系统决定
段的长度不固定,取决于用户编写的程序
分页的用户进程地址空间是一维的,程序员只需要给出一个记忆符即可表示一个地址
分段的用户进程地址空间是二纬的,程序员在表示一个地址时,继续要给出段名,也要给出段内地址
分段比分页更容易实现信息的共享和保护
不能被修改的代码称为纯代码或可重入代码,不属于临界资源,这样的代码是可以共享的,可修改的代码是不能共享的(比如,一个代码段中有很多变量,各进程并发同时访问可能造成数据不一致)
由于分页管理中页面并不是按照逻辑模块划分的,可能一个页面中有的部分可共享,有的部分不能共享,因此很难实现共享
对于分段管理,可以在段表中的段表项增加一个标记是否能被其他进程访问的标志位实现共享
访问一个逻辑地址需要几次访存
分页,考虑单级页表,需要两次访存,一次访问页表,一次访问目标内存单元
分段,两次,一次访问段表,一次访问目标内存单元
都可以引入快表,将近期访问过的段表项放到快表中,这样可以减少一次访问内存,加快地址变换速度
段页式管理方式
分页的优点:内存空间利用率高,不会产生外部碎片,只会有少量的页内碎片
分页的缺点:不方便按照逻辑模块实现信息的共享和保护
分段的优点:很方便按照逻辑模块实现信息的共享和保护
分段的缺点:如果段长过大,为其分配很大的连续空间会很不方便;会产生外部碎片,虽然可以用紧凑方法解决,但是需要付出比较大的时间代价
段页式管理:将进程按照逻辑模块分段,再将各段分页,再将内存空间分为大小相同的内存块/页框/页帧/物理块,将各页面分别装入各内存块中
段页式系统的逻辑地址由段号、页号和页内地址组成,其中页号加页内偏移量就是原来的段内地址
段号的位数决定了每个进程最多可以分几个段
页号位数决定了每个段最大有多少页
页内偏移量决定了页面大小、内存块大小是多少
分段是对用户可见的,程序员编程时需要显式给出段号、段内地址。而将各段分页是对用户不可见的,系统会根据段内地址自动划分页号和页内偏移量,因此段页式管理的地址结构是二维的
段表:每个段对应一个段表项,每个段表项由页表长度、页表存放块号(页表起始地址)组成,每个段表项长度相等,段号是隐含的
页表:每个页面对应一个页表项,每个页表项由页面存放的内存块号组成,每个页表项长度相等,页号是隐含的
一个进程对应一个段表,一个段表项对应一个页表,一个进程对应多个页表
地址转换
存在段表寄存器,存放段表起始地址F和段表长度M
- 根据逻辑地址得到段号S、页号P、页内偏移量W
- 判断段号是否越界,若S≥M,产生越界中断,否则继续执行
- 查询段表,找到相应的段表项,段表项的存放地址为F+S*段表项长度
- 检查页号是否越界,若P≥相应段表项中的页表长度,产生越界中断,否则继续执行
- 根据段表项中的页表存放块号和页号查找页表,找到相应的页表项
- 根据内存块号和页内偏移量得到最终的物理地址
- 访问目标内存单元
三次访存:第一次是访问内存中的段表;第二次是访问内存中的页表;第三次是访问目标内存单元
可以引入TLB,用段号和页号作为查询快表的关键字,若快表命中则仅需一次访存