保护模式2-段描述符与段选择子

  • 当读写段寄存器的时候,只需要给一个16位的段选择子,但是段寄存器的96位的属性都是真实存在,那剩下的80位怎么填充?这个16位的选择子到底应该怎么写?
  • 当我们执行MOV DS,AX这种指令的时候,CPU会根据AX的值来查找GDT表或者LDT表,查表的什么位置

全局描述符表GDT(Global Descriptor Table)在整个系统中,全局描述符表GDT只有一张(一个处理器对应一个GDT),GDT可以被放在内存的任何位置,但CPU必须知道GDT的入口,也就是基地址放在哪里,Intel的设计者门提供了一个寄存器GDTR用来存放GDT的入口地址,程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口地址装入此寄存器,从此以后,CPU就根据此寄存器中的内容作为GDT的入口来访问GDT了。GDTR中存放的是GDT在内存中的基地址和其表长界限


在WinDbg中按Ctrl+Break中断到内核,输入

0: kd> r gdtr        //得到GDT表的基址
gdtr=8003f000
0: kd> r gdtl        //得到GDT表的长度
gdtl=000003ff

0: kd> dq 8003f000   //读取GDT表的内容
8003f000  00000000`00000000 00cf9b00`0000ffff
8003f010  00cf9300`0000ffff 00cffb00`0000ffff
8003f020  00cff300`0000ffff 80008b04`200020ab
8003f030  ffc093df`f0000001 0040f300`00000fff
...

//这里可以简写成dq gdtr
0: kd> dq gdtr
8003f000  00000000`00000000 00cf9b00`0000ffff
8003f010  00cf9300`0000ffff 00cffb00`0000ffff
8003f020  00cff300`0000ffff 80008b04`200020ab
8003f030  ffc093df`f0000001 0040f300`00000fff
8003f040  0000f200`0400ffff 00000000`00000000
8003f050  80008955`87000068 80008955`87680068
8003f060  00009302`2f40ffff 0000920b`80003fff
8003f070  ff0092ff`700003ff 80009a40`0000ffff
  • 0: kd>: WinDbg的命令行等待输入区
  • dd: DWORD
  • dq:QWORD
  • db:string

GDT表的第一个段描述符为00000000`00000000,第二个为00cf9b00`0000ffff


段描述符结构

段描述符


段选择子结构
段选择子

  • RPL:请求特权级别
  • TI:
    • TI=0查GDT表
    • TI=1查LDT表(Windows没有使用)
  • INDEX: 处理器将索引值乘以8再加上GDT表的基址,就是要加载的段描述符

加载段描述符到段寄存器

除了MOV指令,我们还可以使用LES、LSS、LDS、LFS、LGS指令修改寄存器.

    CS不能通过上述的指令进行修改,CS为代码段,CS的改变会导致EIP的改变,要改CS,必须要保证CS与EIP一起改
char buff[6];
__asm
{
	les ecx,fword ptr ds:[buff]  //高两个字节给es,低四个字节给ecx
	char buffer[6] = {0, 0, 0, 0, 0x48, 0};//段选择子0x48
}//RPL<=DPL
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值