1.段描述符与段选择子

80386中段寄存器分别有:
ES CS SS DS FS GS LDTR TR

共96位,其中有16位是可见的,80不可见
至于为什么是96位下面有讲

//结构体表示:
Struct Segment
{
	Word 		selecter		可见部分
	Word 		Atrributes      属性,可读可写可执行
	DWORD 		Base			当前段从哪开始
	DWORD		LinIT			当前段整个有多少
}	

这里写图片描述

mov dword ptr ds:[0x80000000],eax
这段代码执行后就出现异常,段描述符 属性决定了它能不能读写

3~15位为段选择子
1.段描述符与段选择子_第1张图片
此时的ds的为:0x002B,拆成二进制为:
0000000000101 0 11
1.段描述符与段选择子_第2张图片
RPL位为所在的级别:r0,r1,r2,r3。Ti位为0时在GDT中,1时在LDT中

GDT :48位(全局描述符表)LDT(局部描述符表)
LDT只能嵌套的存在GDT中。

GDTR是寄存器,存放着gdt表的基址,GDTL也在gdtr中它指名了gdt表的大小

段描述符的位置 = gdtr首地址 + ds高13位 * 8 。
gdtr一段8字节所以*8

1.段描述符与段选择子_第3张图片

ds.selecter:0x23 00100 0 11
查gdtr:gdtrBase+4*8
1.段描述符与段选择子_第4张图片

段描述符结构:
1.段描述符与段选择子_第5张图片
ds.Base = 00cff300`0000ffff
第一个字节00为段基地址,第四个字节00也为段基地址,结合图看吧…
后面四个字节0000ffff分别为基地址,段限长

3个红部分base:00 00 0000
attr:c f 3
颗粒位G 1时Limit值的单位是4KB,0时Limit值的单位是B
2个蓝部分limit:(0xffff f+1) * 0x1000 - 1 = ffffffff
g位0:fffff补3个0,g位1:fffff补3个f

Base:00000000 共32位
Atrributes :cf3 共16位,不够前面补0补够为止
LinIT:(0xffff f+1) * 0x1000 - 1 = ffffffff 共32为
80+16(可见部分)=96位

**LLDT:**这玩意可以有多个
加载:lldt 0080
假如:ds为0x27转二进制:00100 1 11
1.段描述符与段选择子_第6张图片

读取gdt指令:sgdtL:写lgdt
ldt:sldt/lldt
1.段描述符与段选择子_第7张图片
3环只能读不能写它

你可能感兴趣的:(保护模式)