首页 > 技术文章 > GDT 学习笔记逻辑地址和线性地址计算,因为是自学,所以这只是我的个人理解,不对的请大家指导。

zhj11226 2016-09-30 11:19 原文

在 bochs 刚开始的时候 gdt 是未知的,需要通过实模式的16位代码段初始化 gdt 信息,
在 lgdt 指令之后,即可以使用程序自定义的 GDT 表了。

假如:gdt 初始地址为 0x7c78 (此处根据你的实际情况来定)
描述符表每一个选择符(理解为表的一行)占8个字节,64位;0x7c78 处的内存内容如下

chs:66> info gdt
Global Descriptor Table (base=0x0000000000007c78, limit=23):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00007c60, limit=0x00000014, Execute-Only, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x000b8000, limit=0x0000ffff, Read/Write, Accessed


<bochs:4> x /23bx 0x7c78
[bochs]:
0x0000000000007c78 <bogus+       0>:    0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x0000000000007c80 <bogus+       8>:    0x14    0x00    0x60    0x7c    0x00    0x99    0x40    0x00
0x0000000000007c88 <bogus+      16>:    0xff    0xff    0x00    0x80    0x0b    0x93    0x003 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 02 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
    ==================================================================
值1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0
    0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0
    0x00409900
    0x7c600014
   
值2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 0 0 0 1 0 1 1
    0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    0x0000930b
    0x8000ffff    


如果此时指定 0x0008:0x0010(此即选择子,我的理解就是8的整数倍,但计算地址时只用前面13位, 最后三位用来有别的作用) 则其实际地址计算方法如下:
10x0008 表示描述符在 GDT 表中的位置,即 0x0008/8 = 1,即GDT[0x01]项
2、在 GDT[0x01] 中看到 base=0x7c60, 则线性地址为:0x7c60+0x0010 = 0x7c70

如果此时指定 0x0010:0x0010 则其实际地址计算方法如下:
10x00100x0010/8 = 2, 即 GDT[0x02]项
2、在 GDT[0x02] 中看到 base=0xb8000,则线性地址为:0xb800+0x0010 = 0xb810  <<额,此处有误,应该是 0xb8000 + 0x0010 = 0xb8010

推荐阅读