在 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 0x00
编 3 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 0
号 2 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位, 最后三位用来有别的作用) 则其实际地址计算方法如下:
1、0x0008 表示描述符在 GDT 表中的位置,即 0x0008/8 = 1,即GDT[0x01]项
2、在 GDT[0x01] 中看到 base=0x7c60, 则线性地址为:0x7c60+0x0010 = 0x7c70
如果此时指定 0x0010:0x0010 则其实际地址计算方法如下:
1、0x0010 即 0x0010/8 = 2, 即 GDT[0x02]项
2、在 GDT[0x02] 中看到 base=0xb8000,则线性地址为:0xb800+0x0010 = 0xb810 <<额,此处有误,应该是 0xb8000 + 0x0010 = 0xb8010
