在 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