转自:
点击打开链接
/* author: mik
* project: pm_simulation (一个保护模式行为模拟器)
*
* sregister.h 这个文件描述段管理的几个相关寄存器的结构
*/
#ifndef __SREGISTER__
#define __SREGISTER__
/* 选择子共16位长 */
typedef struct selector { unsigned short RPL : 2; /* Bit0~Bit1: 请求权限 */ unsigned short TI : 1; /* Bit2: 描述符表索引 */ unsigned short SI : 13; /* Bit3~Bit15: 描述符索引 */ } SELECTOR; /* 段寄存器2部分:16位的选择子域,是可视部分;48位不可视部分,由处理器自动设置 */ typedef struct segment_reg { SELECTOR selector; /* 段寄存器中的选择子域:是可用域 */ unsigned attributes : 16; /* 段属性:2个字节宽,不可用域 */ unsigned limit : 32; /* 段长:4个字节宽,不可用域 */ unsigned base : 32; /* 段基地址:4个字节宽,不可用域 */ } __attribute__((packed)) SEGMENT_REG; /* 全局描述符表寄存器及中断描述符表寄存器结构 */ typedef struct { unsigned short limit; /* 描述符表长度 */ unsigned base; /* 描述符表基址 */ } GDT_REG, IDT_REG;
/* 局部描述符表寄存器及任务寄存器结构 */
typedef SEGMENT_REG LDT_REG, TASK_REG;
#endif
|
一、选择子结构
RPL: 为访问请求选择子的权限级别,分为:0、1、2、3 共4个级别。通常配合 CPL(当前运行级别)以及 DPL(描述符设置的对段的访问权限级别)三者进行权限的检查。
TI: 为 0 时,是基于全局描述符表进行索引。为 1 时,是基于局部描述符表进行索引。
SI: 此域为描述符表的索引值。共13位,可索引的描述符为8192个描述符。
当 SI 为 0 时,仅当 TI == 0 时,才是合法的索引值,此时为全局描述符表的第1个表项。当 T == 1时,将会产生 #GP 保护异常
二、段寄存器结构
分为两部分:一部分是对于软件来说是可见的。另一部分是不可见的,由处理器自动设置。
selector 域是可见的。当执行 mov cs,.. mov ds.. 等指令时,将加载进段寄存器。
attribute、limit 及 base 是不可见部分。当经过索引获取描述符后,处理器自动将描述符相关域加载进入这些部分。
三、全局描述符表寄存器(GDTR)及中断向量描述符表寄存器(IDTR)
这2个寄存器的结构是一致的。16位的限长加上32位的基址,指出描述符表的基地址。描述符表基地址可以定义在内存空间地址的任何一个地方。但处理器将会实行4 byte的地址对齐策略。
四、局部描述符表寄存器(LDTR)及任务描述符表寄存器(TR)
这2个寄存器结构与段寄存器结构一致,也是一种load into selector ,然后处理器自动加载的行为。与 GDT 表一样,LDT 及 TSS 也可以定义在任一个基地址,而实行4byte对齐策略。