段描述符与段选择子

段描述符与段选择子

段寄存器有96位,其中80位不可见,包括Base,limit,attribute。16位可见,即段选择子selector。

对段寄存器进行写入时,CPU根据段选择子到GDT表中寻找段描述符,段描述符共8字节,64位,CPU根据段描述符填充段寄存器。

那么问题就是,如何用64位的段描述符来填充80位的段寄存器呢?为了解决该问题,这就需要段描述符的P,G位。

一、段描述符结构如图:

https://i-blog.csdnimg.cn/blog_migrate/ca1db6e36c52852800291b3ffb84ce60.png BASE: 段基址,由上图中的两部分(BASE 31-24 和 BASE 23-0)组成

G:LIMIT的单位,该位 0 表示单位是字节,1表示单位是 4KB

由于Intel考虑向前兼容,我们会发现段描述符的结构比较混乱,东一块西一块的。Attribute在段描述符高4字节的8-23位,Base在段描述符的低4字节的16-31位,高4字节的0-7位和24-31位。上述两个属性没有数据丢失,段寄存器和段描述符内的位数是一样多的。而Limit在段寄存器内占32位,在段描述符内只有20位。

当G=0时,Limit的范围是0x00000000-0x000FFFFF,其中,段描述符的20位在低位,高位补0.

当G=1时,Limit的范围是0x00000FFF-0xFFFFFFFF,其中,段描述符的20位在高位,低位补F。

D/B: 该位为 0 表示这是一个 16 位的段,1 表示这是一个 32 位段

AVL: 该位是用户位,可以被用户自由使用

LIMIT: 段的界限,单位由 G 位决定。数值上(经过单位换算后的值)等于段的长度(字节)- 1。

P: 当P=1时,段描述符有效;当P=0时,段描述符无效。

DPL:段权限

S: 该位为 1 表示这是一个数据段或者代码段。为 0 表示这是一个系统段(比如调用门,中断门等)

TYPE: 根据 S 位的结果,再次对段类型进行细分。

二、段选择子

段选择子是一个16位的段描述符,段选择子格式,如图:

https://i-blog.csdnimg.cn/blog_migrate/a0e78992cf78f3ce53306ea6203afd3b.png

INDEX:在GDT数组或LDT数组的索引号(3~15位)

TI:Table Indicator,这个值为0表示查找GDT,1则查找LDT

RPL:请求特权级。以什么样的权限去访问段。

 

三.练习:

给出下列3个段选择子,从GTD表中查找对应的段描述符,然后填充到段寄存器中。

将段描述符填写到段寄存器结构体中(段选择子:23, 2B ,30 )

0x23 拆分为二进制为 : 0010 0011

RPL :11 (低2位)

TI :0 (第3位)

INDEX : 100 (3~15位)

表明查找GDT表,Index 是4。对应GDT表项是00cff300`0000ffff

WORD Selector: 23

WORD Atrribute: cff3

DWORD Base: 00000000

DWORD Limit: ffffffff

 

0x2B 拆分为二进制为 :00101 0 11

RPL :11 (低2位)

TI :0 (第3位)

INDEX : 101 (3~15位)

表明查找GDT表,Index 是5。对应GDT表项是80008b04`200020ab

WORD Selector: 2B

WORD Atrribute: 008b

DWORD Base: 80042000

DWORD Limit:000020ab

 

0x30 拆分为二进制为 :00110 0 00

RPL :00 (低2位)

TI :0 (第3位)

INDEX : 110 (3~15位)

表明查找GDT表,Index 是6。对应GDT表项是ffc093df`f0000001

WORD Selector: 30

WORD Atrribute: c093

DWORD Base: ffdff000

DWORD Limit: 00001fff

 

四、加载段描述符至段寄存器

mov 指令修改段寄存器,例如:

mov ax, 0x20

mov ds, ax

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

CS不能通过上述的指令进行修改,CS为代码段,CS的改变会导致EIP的改变,要改CS,必须要保证CS与EIP一起改。

int main()

 {

       char buffer[6] = {0};

       __asm {

              // 高 2 字节加载到 ES 寄存器,低 4 字节复制到 ecx 寄存器。fword 表示 6 字节。

              // LDS/LSS/LFS/LGS 用法是类似的。没有LCS指令,要修改CS,需要使用其它指令,这里就不给出。

              // 这行指令是有坑的,不一定可以执行成功,取决于buffer中的值。

              les ecx, fword ptr ds:[buffer]

       }

       return 0;

}

注意:RPL<=DPL(在数值上)

五、分析 limit

limit 的含义是这个段的大小。 LIMIT 表示段描述符中的 20bit LIMIT。

如果粒度 G=0,LIMIT= 0x3ff,这意味着该段的大小是 0x3ff+1=0x400 字节。如果 G=1,那意味着该段的大小是(0x3ff+1)*4KB=0x400000字节,所以换算后的 limit = 0x400000-1=0x003fffff.

再举个例子。LIMIT=0xfffff, G=1,则该段的大小是 (0xfffff+1)*4KB=0x100000*0x1000=0x100000000字节,所以换算后的 limit=0x100000000-1=0xffffffff

limit 只有20个位,如何赋给32位呢 ?

当属性里的G位为0时,在limit 高位添加12个0,扩展为32位。比如 0x003ff,然后在前面补 0 至32bit,即 limit = 0x000003ff;

当G位为1时,在limit 低位添加12 个1(二进制),扩展成32 位。比如 0x003ff,然后在后面补 f 至 32bit, 即 LIMIT = 0x003fffff

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值