我对LDTR GDTR 和GDT ,LDT的转换理解
ccccj 2008-10-11 07:44:24 段xxxx:偏移yyyyyyyy
首先,xxxx是无法表示段的基址的,对于这个地址,首先要看xxxx的TI位是否为0(即xxxx的第二位),如果是,则从GDTR中获取GDT的基址,然后在GDT中以段选择器xxxx的高12位得出索引,根据索引偏移找到相应的段描述符,段描述符包括段的基址,限长,优先级各种属性,这就得到了段的起始地址,加上yyyyyyyy即是要找的内存的线性地址zzzzzzzz。 如果TI位为1,则表示段描述符放在LDT中,第一步的操作还是从GDTR中获取GDT的基址,然后从LDTR寄存器获得索引(非XXXX的高十二位),注意,这时根据索引偏移得到得并不是段描述符,而是得到LDT段的位置,然后根据xxxx的高十二位从LDT段中获得段描述。再以这个段描述符信息得到段基址,再加上偏移yyyyyyyy得到要找的线性地址zzzzzzzz。可以写个简单的模拟程式来表示:
if( xxxx的第二位==1 ) //段描述符的位置在GDTR中
{
A1=(GDTR的前三十二位); //把GDTR的基址给A1
段描述符=A1+(xxxx的高12位); //可获得段描述符
线性地址 = 段描述符中的基址+yyyyyyyy;
}
else //TI位为0,表示在段描述符在LDT中
{
A1=(GDTR的前三十二位);
A2=A1+LDTR; //A2即是LDT描述符表的入口,注:LDTR是16位的 (自己注释:GDTR只有一张表,而且基地址(在内核中)确定的,任务切换时候,也不会改变!每个LDTR又是指向自己任务的,所以任务切换时候,只是改变LDTR寄存器中的内容(改变在GDT中的索引),找到另一个LDT段的描述符(包含了LDT的开始基地址和界限),然后加上段选择子的索引,找出地址中的位置!),还要要注意的是LDT表的基地址和界限是在LDT的高速缓存中,任务不切换的话,v高速缓存高速缓存的内容不会变!
段描述符=A2+(xxxx的高十二位) //LDT描述符表入口加上偏移,即是相应的段描述符 自己注释:书上写的A2(应该是表示从LDT的开始基地址吧)LDT的基地址+索引才是局部描述符正确的位置
线性地址 = 段描述符中的基址+yyyyyyyy;
}
不正确的地方大家帮我指出来哦,谢谢大家了