简单易懂,基本分段管理存储

基本分段存储管理 (Segmentation)

我们来深入探讨另一种重要的非连续分配方式——分段存储管理 (Segmentation)。如果说分页是基于物理尺寸的“一刀切”,那么分段就是基于程序逻辑的“智能组合”。

为了理解分段,我们使用一个全新的比喻:你是一位剧作家,正在创作一部多幕话剧剧本

  • 进程:整部话剧的完整剧本
  • 逻辑段:剧本中逻辑上独立的组成部分,如**“第一幕”、“第二幕”、“演员列表”、“道具清单”**等。
  • 内存:一个巨大的、有多层搁板的文件柜,用来存放剧本的各个部分。
  • 分段存储:一种整理剧本手稿的方法。

1. 分段的概念:按“逻辑功能”组织剧本

在分页管理中,我们会不分青红皂白地把整部剧本按固定页数(如每10页)切成一沓一沓。这种方法很机械,可能导致“第一幕”的结尾和“第二幕”的开头被分在同一沓纸里。

分段管理则完全不同,它完全尊重剧本的内在逻辑结构:

  • “第一幕” 的所有手稿,整理成一沓,形成“第一幕段”。
  • “第二幕” 的所有手稿,整理成另一沓,形成“第二幕段”。
  • “演员列表” 和 “道具清单” 也各自形成独立的段。

核心特点

  • 逻辑单位:每个“段”都是一个逻辑上完整的单元。比如一个完整的函数、一个数组、一个代码块或数据区。
  • 大小不一:“第一幕段”可能很长,“演员列表段”可能就一页纸。每个段的长度是不固定的,取决于其逻辑内容的大小。
  • 程序员可见:作为剧作家(程序员),你非常清楚地知道剧本有“第一幕”、“第二幕”等几个部分,你在创作和组织时,就是以这些段名为单位来思考的。
  • 离散存放:“第一幕段”可以放在文件柜的顶层,“第二幕段”可以放在底层。每个段在文件柜里各自占据一块连续的空间,但段与段之间可以不相邻

2. 逻辑地址结构:从“剧本第几页”到“第几幕的第几行”

现在,导演(CPU)想要排练剧本里的某句台词,他对助理(地址变换机构)下达指令的方式也变了。他不会说“我要剧本的第5000行”,而是说:“我要 ‘第二幕’(段号) 的第325行 (段内地址)”。

所以,分段管理的逻辑地址是二维的:

逻辑地址 = (段号 S, 段内地址/偏移量 W)

  • 段号 (S):指定是哪个逻辑段(比如“第一幕”、“道具清单”)。
  • 段内地址 (W):指定在该段内的偏移位置(比如第几行、第几个字节)。

3. 段表:剧本的“内容索引卡”

为了能快速找到每个幕的剧本手稿被放在了文件柜的哪个位置,我们在文件柜的抽屉里放了一套索引卡片(段表, Segment Table)

  • 段表的作用:记录每个逻辑段到物理内存位置的映射。
  • 段表项的构成:每一张索引卡片(段表项)都对应一个段(如“第一幕”),上面记录了三条关键信息:
    1. 段号:这张卡片是关于哪个段的(通常是隐含的,作为数组下标)。
    2. 段长 (Limit):这个段有多厚/多长(有多少行/字节)。这是必须的,因为每个段大小不一,需要用它来检查访问是否越界。
    3. 段基址 (Base):这个段在文件柜里是从哪个位置开始放的(在内存中的起始物理地址)。

4. 地址变换过程:图书管理员的“两步安全检查”

当导演(CPU)需要某句台词时,图书管理员(地址变换机构)会进行一次非常严谨的查找,包含两次重要的安全检查。

导演发出指令:“我要找段号为S,段内地址为W的内容!”

  1. 第一步:检查段号是否合法(是否存在这一幕?)

    • 管理员先查看段号S,然后对比段表长度寄存器 (STLR)(记录了总共有多少个段/幕)。
    • 如果 S >= 段表长度,说明导演在找一个不存在的幕(比如“第五幕”),立刻“报警”(地址越界中断)。
  2. 第二步:查索引卡,找段的位置和长度

    • 段号合法后,管理员根据段表起始地址寄存器 (STBR) 和段号S,计算出对应索引卡片(段表项)的位置 (STBR + S * 段表项大小),第一次访问内存,取出这张卡片。
    • 从卡片上读出两个信息:段长 L 和 段基址 B
  3. 第三步:检查段内地址是否合法(台词是否超出了这一幕的范围?)

    • 这是第二次安全检查。管理员会检查导演想要的行号W是否超过了这一幕的总长度L
    • 如果 W >= 段长 L,说明想找的台词超出了这一幕的剧本范围,同样“报警”(地址越界中断)。
  4. 第四步:计算最终物理地址

    • 所有检查都通过后,管理员用该幕剧本的起始位置B和想要的行号W相加,得到最终在文件柜里的物理位置。
    • 物理地址 = 段基址 B + 段内地址 W
    • 然后第二次访问内存,从这个位置取出那句台词交给导演。

5. 分段 vs. 分页:一场深刻的哲学对决

这是操作系统面试和考试中永恒的经典问题。

对比维度分页 (Paging)分段 (Segmentation)比喻
单位性质物理单位逻辑单位机械地每10页切一沓 vs. 按幕/章/节划分
划分依据系统固定大小程序自身逻辑结构机器说了算 vs. 程序员/编译器说了算
大小固定 (由系统决定)不固定 (由逻辑段决定)每沓纸页数一样 vs. 每幕剧本长度不同
对用户可见性透明 (不可见)可见用户感觉不到分页 vs. 用户需按段名组织程序
地址空间一维二维只需要一个线性地址 vs. 需要(段号,段内地址)
碎片内部碎片 (最后一页不满)外部碎片 (段间的小空闲区)最后一沓纸的空白页 vs. 文件柜搁板上的零散空隙
共享与保护不方便,粒度粗方便,粒度细共享一沓无意义的纸 vs. 共享整个“演员列表”段

核心区别

  • 分页的目的是为了提高内存利用率,满足操作系统自身的管理需求。它对用户是完全透明的,用户感知不到自己的程序被“肢解”了。分页是面向机器的。
  • 分段的目的是为了更好地满足用户的编程需求。它使得程序可以按逻辑模块组织,便于分别编译、共享和保护。用户在编程时,是以“段”为单位来思考的。分段是面向用户/程序员的。

必会题与详解

题目一:在分段存储管理中,地址变换过程需要进行两次合法性检查,请问是哪两次?它们分别是为了防止什么问题?

答案详解

需要进行以下两次合法性检查:

  1. 段号越界检查:将逻辑地址中的段号S段表长度寄存器 (STLR) 中的值进行比较。

    • 目的:是为了防止进程访问一个不存在的逻辑段。比如一个进程只定义了3个段(段号0,1,2),但它试图访问段号为3的段,这个检查就会捕获到这个非法访问。
  2. 段内地址越界检查:将逻辑地址中的段内地址W与从段表中查出的该段的**段长L**进行比较。

    • 目的:是为了防止进程访问超出其自身逻辑段边界的内存区域。比如一个函数(段)只有100个字节长,但程序试图访问该段的第101个字节,这个检查就会捕获到这个错误,从而保护了其他段或进程的内存空间不被破坏。

题目二:为什么说分段管理比分页管理更有利于实现程序的共享和保护?

答案详解

因为段是信息的逻辑单位,而页是物理单位。

  1. 共享 (Sharing)

    • 在分段系统中,一个逻辑上完整的单位,如一个函数库、一个公用数据区,可以被定义为一个独立的段。当多个进程需要共享这个函数库时,只需要在它们各自的段表中,都增加一个指向这个物理内存段的段表项即可。这种共享是有意义的、清晰的
    • 而在分页系统中,一个逻辑上完整的函数可能会被切割到两个或多个页面中。要共享这个函数,就需要共享多个毫无逻辑关联的页面,管理起来非常困难和不直观。
  2. 保护 (Protection)

    • 由于段是逻辑单位,我们可以很方便地对不同的段赋予不同的访问权限。例如,可以把代码段设置为“只读”,数据段设置为“可读可写”,而另一个敏感数据段则设置为“仅限内核访问”。这种基于逻辑意义的保护非常自然和有效。
    • 而在分页系统中,对一页内存设置保护权限,但这页内存里可能既包含了一部分代码,又包含了一部分数据,很难进行精细化的、有意义的权限控制。

题目三:一个分段系统的逻辑地址由16位段号和16位段内地址组成。请问,一个进程最多可以有多少个段?每个段的最大长度是多少?

答案详解

  1. 最大段数

    • 段号由16位二进制数表示。
    • 16位可以表示 2^16 个不同的值(从0到2^16 - 1)。
    • 因此,一个进程最多可以拥有 2^16 个段,即 65536 个段。
  2. 每段的最大长度

    • 段内地址由16位二进制数表示。
    • 16位可以表示 2^16 个不同的偏移量(从0到2^16 - 1)。
    • 假设系统是按字节编址的,那么每个段的最大长度就是 2^16 字节(B)。
    • 2^16 B = 2^6 * 2^10 B = 64 * 1 KB = 64 KB
    • 因此,每个段的最大长度是 64KB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值