当前位置: 首页 > news >正文

windows中 GDTR和GDT关于快速调用的实现1

windows中 GDTR和GDT关于快速调用的实现1

windows中 GDTR和GDT关于快速调用的实现1

文章目录

  • windows中 GDTR和GDT关于快速调用的实现1
  • 一、全局表述表
  • 二、选择子


一、全局表述表

为进一步理解上面我们讲的两条指令(sysenter,sysexit).,我在解释一个”全局段描述符表(Global Descriptor Table)“即GDT及其段寄存器之间的关系,CPU中的系统寄存器GDTR指向内存中的GDT,这是一个结构数组。数组中的每一个表象都是一个64位的KGDTENTRY数据结构,里面描述了段的起点和大小,保护模式,访问权限等信息。合在一起就是一个64位的段描述块。数组的大小位NUM_GDT,定义为28
GDT的定义

//
// GDT Entry Definition
//
typedef struct _KGDTENTRY
{USHORT LimitLow;USHORT BaseLow;union{struct{UCHAR BaseMid;UCHAR Flags1;UCHAR Flags2;UCHAR BaseHi;} Bytes;struct{ULONG BaseMid:8;ULONG Type:5;ULONG Dpl:2;ULONG Pres:1;ULONG LimitHi:4;ULONG Sys:1;ULONG Reserved_0:1;ULONG Default_Big:1;ULONG Granularity:1;ULONG BaseHi:8;} Bits;} HighWord;
} KGDTENTRY, *PK

NUM_GDT的定义

// Descriptors
#define NUM_GDT 28 //15. The kernel wants 0xD8 as a last GDT entry offset
#define NUM_IDT 0x100 // only 16 are used though

二、选择子

在32位保护模式下,段寄存器的内容成为“选择项(Selector)",其主题部分即高13位就是用于GDT或者“局部描述段描述表(Local Descriptor Table)即LDT的下标。剩下的3位,bit2位LDT/GDT的选择位,位0表示选择GDT,为1表示选择LDT,最低两位则为RPL即运行权限,0表示0环系统态,
然而段寄存器所指向的段究竟在哪里,有多大,属于R0还是R3,则有具体的断描述符决定。下面是几个下标的定义

代码如下(示例):

//
// Selector Names
//
#ifdef __ASM__
#define RPL_MASK                                0x0003
#define MODE_MASK                               0x0001
#define KGDT_R0_CODE                            (0x8)
#define KGDT_R0_DATA                            (0x10)
#define KGDT_R3_CODE                            (0x18)
#define KGDT_R3_DATA                            (0x20)
#define KGDT_TSS                                (0x28)
#define KGDT_R0_PCR                             (0x30)
#define KGDT_R3_TEB                             (0x38)
#define KGDT_LDT                                (0x48)
#define KGDT_DF_TSS                             (0x50)
#define KGDT_NMI_TSS                            (0x58)
#endif

不要忘记了选择项的高13位才是下表,所以KGDT_R3_CODE 定义为0x18,去掉低三位对应的下表是3.
由于是用户空间的段选择项,其最低两位值应该是3,所以用户空间的空间段选择项实际上是1b,即(KGDT_R3_CODE | RPL_MASK).这里的RPL_MASK 定义为0x0003,但是,KGDT_R0_CODE所对应的下标是1.段选择值是0x8.因为这是系统空间的代码段。最低两位为0,至于下标0,则是禁用

由此可见,对于这样选择值的数值上的安排,实际上是各种段选择快在GDT中的位置,必须遵循某种规则。我们前面看到SYSENTER_CS_MSR的内容是KGDT_R0_CODE.所以指令sysenter置入CS的KGDT_R0_CODE,加上0就是KGDT_R0_DATA;
而sysexit置入CS的是KGDT_R3_CODE,置入SS的KGDT_R0_DATA.(注意sysexit会自动把cs,ss的RPL段设置为3)正因为这样。在R0空间堆栈中就无需保存用户空寂的那的堆栈段选择项SS

未完。。。


http://www.mrgr.cn/news/51294.html

相关文章:

  • 生信软件38 - 基因型填充软件IMPUTE2
  • 重磅优惠,节省高达56%
  • Spring专题
  • misc-stuff: jump into thinking
  • 【Python机器学习】入门机器学习算法,打造智能应用!
  • 河源市社保卡照片要求及手机自拍拿数码相片回执的方法
  • 代码随想录算法训练营第三十五天|452. 用最少数量的箭引爆气球,435. 无重叠区间,763. 划分字母区间
  • ESP-01S WIFI模块指南
  • 代码提交后服务器项目同步更新
  • 解锁传音控股的“500强”实力:创新力是站稳市场的关键
  • 一文了解数字孪生是什么?数字孪生赋能哪些行业应用场景
  • CloudDM Team - 全新的企业级数据库数据安全管控平台
  • Windows Tomcat 图文详细教程(包括环境配置)
  • 小猿口算脚本
  • closerAI comfyUI 以假乱真,掂!超真实flux pulid角色一致性换脸工作流,实现超真实的写真艺术照摄影
  • Unity Spine优化思路
  • 【Flutter】Dart:环境搭建
  • c++项目中无法跳转到头文件/无法搜索到头文件
  • 北京大学冯惠:与卓越者同行,方能更快的成长 | OceanBase数据库大赛获奖选手访谈
  • C++的忠实粉丝-继承的热情(1)