◆ 正在回复 匿名 () 于 2013-11-30 20:44:50 发表的题目为 你好,sd = gdt + S16 & 0xFFF8; 这里S16好像得先往右移3位,然后再与操作吧 的留言, 原文为:
这样, 段寄存器通过查询 GDT/LDT 表获得段的基址后, 再加上偏移得到一个 32 位的地址. 这个地址被称为线性地址. 如果没有启用下面说的分页机制, 那么线性地址就是物理地址. 如果启用了分页机制, 线性地址还需要经过一次映射才能得到物理地址. 综上, 虚拟地址到线性地址的映射关系可用如下伪代码来描述:
if(S16 & 0x04 == 0) // 取段寄存器的第 3 位, 判断是使用 GDT 还是 LDT
{ // 使用 GDT
gdt = (GDTR >> 16) & 0xFFFFFFFF; // 取 GDTR 寄存器的高 32 位, 既 GDT 表的起始地址.
sd = gdt + S16 & 0xFFF8; // 根据段寄存器中的索引号找到段描述符
sbase_l = (sd >> 12) & 0x00FFFFFF; // 取基址的低 24 位
sbase_h = (sd >> 32) & 0xFF000000; // 取基地址高 8 位
sbase = sbase_h | sbase_l;
return sbase + P32 // 基址加上偏移得到最终的线性地址
}