我正在阅读mit os内核代码的反汇编代码。我认为内核代码应遵循相同的规则。
我看到内核中加载全局描述符表的指令如下: lgdtl 0x10f018
我知道lgdt将GDT的长度(16位)和GDT的地址(32位)作为操作数。但是,我不知道GDT的地址来自命令。
我检查了从0x10f0和0xf018开始的8字存储器内容。从这两个地址开始的所有8个字都是零。
我的问题是:
lgdtl 0x10f018
的GDT地址是什么?你是怎么说的?这台机器是intel 32bit。
是否有任何寄存器持有GDT的地址?我正在使用bochs来运行操作系统,所以如果我知道寄存器,也许我可以打印出寄存器的内容。
非常感谢你的帮助!
[变形例] 我看了acround,发现lgdtl ADDR意味着将ADDR的内容加载到GDTR。因此,ADDR的内容是GDT的限制和地址。我在0x10f018打印出内存内容:
<bochs:24> x /8wx 0x10f018
[bochs]:
0x0010f018 <bogus+ 0>: 0xf0000017 0x00000010 0x32311b00 0x36353433
0x0010f028 <bogus+ 16>: 0x30393837 0x09083d2d 0x72657771 0x69757974
以下是GDT的设置
###################################################################
# setup the GDT
###################################################################
.p2align 2 # force 4 byte alignment
mygdt:
SEG_NULL # null seg
SEG(STA_X|STA_R, -KERNBASE, 0xffffffff) # code seg
SEG(STA_W, -KERNBASE, 0xffffffff) # data seg
mygdtdesc:
.word 0x17 # sizeof(mygdt) - 1
.long RELOC(mygdt) # address mygdt
我的问题是:如何解释
0x0010f018 <bogus+ 0>: 0xf0000017 0x00000010 0x32311b00
获取GDT的地址?
BTW,0x00f01000的内容如下。我以为它可能是GDT,但不是。 :(任何人都可以帮忙吗?
<bochs:31> x /16wx 0x00f01000
[bochs]:
0x00f01000 <bogus+ 0>: 0x00000000 0x00000000 0x00000000 0x00000000
0x00f01010 <bogus+ 16>: 0x00000000 0x00000000 0x00000000 0x00000000
0x00f01020 <bogus+ 32>: 0x00000000 0x00000000 0x00000000 0x00000000
0x00f01030 <bogus+ 48>: 0x00000000 0x00000000 0x00000000 0x00000000
解决:
<bochs:29> x /6bx 0x10f018
[bochs]:
0x0010f018 <bogus+ 0>: 0x17 0x00 0x00 0xf0 0x10 0x00
基于小edian,寄存器有0010f000 0017 所以GDT的地址是0010f000,长度是0017; 通过查看0010f000的内容确认了这一点:
<bochs:32> x /8wx 0x0010f000
[bochs]:
0x0010f000 <bogus+ 0>: 0x00000000 0x00000000 0x0000ffff 0x10cf9a00
0x0010f010 <bogus+ 16>: 0x0000ffff 0x10cf9300 0xf0000017 0x00000010
此外,初始esp指向0x0010f000,这是GDT的起始地址。调用第一个函数时,堆栈从较高地址增加到较低地址。
存储器映射如下(左侧是低位地址):
---程序堆栈--- | GDT