全局描述符表的物理地址?

时间:2014-01-15 02:56:44

标签: c linux assembly linux-kernel

我正在阅读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

1 个答案:

答案 0 :(得分:2)

GDT基本上是一个包含各种GDT条目的结构。 lgdtl是将全局描述符表加载到gdt寄存器的指令。那么,回答你的问题:0x10f018是GDT基地址。如果查看代码,您会发现GDT定义为结构,0x10f018是该结构的地址(根据您的反汇编),在GDT结构中最多可以有8192个条目。

所以,是的GDT寄存器保存GDT结构的基址。 lgdt用于设置gdt,其格式如下:lgdt maddr。并且,在设置GDT之前,打印寄存器内容的计划不起作用,因为设置GDT的唯一方法是使用lgdt

希望这会有所帮助!另请参阅以下有关清除GDTLGDT

概念的参考资料