保护模式 - 2.段描述符

段描述符

20210325151734

  • S位:用于指定述符的类型(Descriptor Type)。当该位是“0”时,表示是一个系统段;为“1” 时,表示是一个代码段或者数据段(堆栈段也是特殊的数据段)
  • DPL:表示述符的特权级(Descriptor Privilege Level,DPL)。这两位用于指定段的特权级。共 有 4 种处理器支持的特权级别,分别是 0、1、2、3,其中 0 是最高特权级别,3 是最低特权级别。 刚进入保护模式时执行的代码具有最高特权级 0(可以看成是从处理器那里继承来的),这些代码通 常都是操作系统代码,因此它的特权级别最高。每当操作系统加载一个用户程序时,它通常都会指 定一个稍低的特权级,比如 3 特权级。不同特权级别的程序是互相隔离的,其互访是严格限制的, 而且有些处理器指令(特权指令)只能由 0 特权级的程序来执行,为的就是安全
  • G位是粒度(Granularity)位,用于解释段界限的含义。当 G 位是“0”时,段界限以字节为 单位。此时,段的扩展范围是从 1 字节到 1 兆字节(1B~1MB), 因 为 述 符 中 的 界 限 值 是 20 位 的。相反,如果该位是“1”, 那 么 , 段 界 限 是 以 4KB 为单位的。这样,段的扩展范围是从 4KB 到 4GB。
  • P位 段是否有效 1有效 0无效
  • D/B 位是“默认的操作数大小”(Default Operation Size)或者“默认的堆栈指针大小”(Default Stack Pointer Size),又或者“上部边界”(Upper Bound)标志,主要为了能够在32位处理器上兼容运行16位保护模式的程序
    • D:代码段 用于指示指令中默认的 偏移地址和操作数尺寸。D=0 表示指令中的偏移地址或者操作数是 16 位的;D=1,指示 32 位的 偏移地址或者操作数
    • B:堆栈段 用于在进行隐式的堆栈操作时,是使用 SP 寄存器还是 ESP 寄存器。隐式的堆栈操作指令包括 push、pop 和 call 等。如果该位是“0”,在访问那个段时, 使用 SP 寄存器,否则就是使用 ESP 寄存器。同时,B 位的值也决定了堆栈的上部边界。如果 B=0, 那么堆栈段的上部边界(也就是 SP 寄存器的最大值)为 0xFFFF;如果 B=1,那么堆栈段的上部 边界(也就是 ESP 寄存器的最大值)为 0xFFFFFFFF。
    • B=0 G=1 向上拓展 在普通数据段(ES,DS,FS,GS) B=0 是无效的
  • TYPE 字段共 4 位,用于指示述符的子类型,或者说是类别。

    • 对于数据段来 说,这 4 位分别是 X、E、W、A 位;

      X E W A 描述符类别 含义
      0 0 0 X 数据 只读
      0 0 1 X 数据 读,写
      0 1 0 X 数据 只读,向下扩展
      0 0 0 X 数据 读,写,向下扩展
    • 对于代码段来说,这 4 位则分别是 X、C、R、A 位;

      X C R A 描述符类别 含义
      1 0 0 X 代码 只执行
      1 0 1 X 代码 执行,读
      1 1 0 X 代码 只执行,依从的代码段
      1 1 1 X 代码 执行,读,依从的代码段
    • X 表示是否可以执行(eXecutable)。数据段总是不可执行的,X=0;代码段总是 可以执行的,因此,X=1

    • A 数据段和代码段的 A 位是已访问(Accessed)位,用于指示它所指向的段最近是否被访问过。 在述符创建的时候,应该清零。之后,每当该段被访问时,处理器自动将该位置“1”。对该位的 清零是由软件(操作系统)负责的,通过定期监视该位的状态,就可以统计出该段的使用频率。当 内存空间紧张时,可以把不经常使用的段退避到硬盘上,从而实现虚拟内存管理。

    • 对于数据段来说

      • E 位指示段的扩展方向。E=0 是向上扩展的,也就是向高地址方向扩展的,不包含limit, 是普通的数据段;E=1 是向下扩展的,也就是向低地址方向扩展的,包含limit,通常是堆栈段
      • W 位指示段 的读写属性,或者说段是否可写,W=0 的段是不允许写入的,否则会引发处理器异常中断;W=1 的段是可以正常写入的
    • 对于代码段来说

      • C 位指示段是否为特权级依从的(Conforming)。 C=0 表示非依从的代码段, 这样的代码段可以从与它特权级相同的代码段调用,或者通过门调用;C=1 表示允许从低特权级的 程序转移到该段执行。
      • R 位指示代码段是否允许 读出。代码段总是可以执行的,但是,为了防止程序被破坏,它是不能写入的。至于是否有读出的可 能,由 R 位指定。R=0 表示不能读出,如果企图去读一个 R=0 的代码段,会引发处理器异常中断; 如果 R=1,则代码段是可以读出的,即可以把这个段的内容当成 ROM 一样使用。
        • 码段是不可读的,那处理器怎么从里面取指令执行呢?事实上,这里的 R 属性并非用来限制处理器,而是用来限制程序和指令的行为。一个典型的例子是使用段超越前缀 “CS:”来访问代码段中的内容
评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...