2

bootasm.S

.p2align 2                                # force 4 byte alignment
gdt:
  SEG_NULLASM                             # null seg
  SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff)   # code seg
  SEG_ASM(STA_W, 0x0, 0xffffffff)         # data seg

gdtdesc:
  .word   (gdtdesc - gdt - 1)             # sizeof(gdt) - 1
  .long   gdt                             # address gdt

这用于

lgdt gdtdesc

gdtdesc 的第一个字不应该是 gdt 的大小(以字节为单位)吗?在这种情况下,它是3*8=24,它等于gdtdesc - gdt。为什么gdtdesc - gdt - 1在这里?

4

1 回答 1

5

根据手册,lgdt想要以字节为单位的 GDT 大小,但也将其描述为“限制”。该措辞在大小与最后一个字节的地址之间是模棱两可的。(作为一种在不包装 16 位限制的情况下允许更高限制的方法是有意义的。)

但是https://wiki.osdev.org/GDT_Tutorial中的示例使用 sizeof(gdt) 所以这是 xv6 或 osdev 教程中的错误。

https://wiki.osdev.org/Global_Descriptor_Table同意 xv6,说“限制”是 size-1,不像 GDT 教程。这是有道理的:

size是表的大小减 1。这 是因为 size 的最大值是 65535,而 GDT 最多可以是 65536 字节(最多 8192 个条目)。此外,没有 GDT 的大小可以为 0。

如果您想确认详细信息,请查看 Intel 或 AMD 的手册;他们希望在系统开发细节的某个地方澄清这一点,与lgdt.

或者你希望他们会。但不幸的是,英特尔说:

2.4.1 节全局描述符表寄存器(GDTR)

“表限制指定表中的字节数”。

这可能只是意味着写它的人都陷入了限制 = 最后一个字节的偏移量 = 大小的想法,以至于他们甚至没有意识到这一点并不清楚。段限制本身(在 GDT 条目中)也以这种方式工作,使用0xFFFFF(粒度=页面)将限制指定为 4GiB 地址空间的最顶部,即无限制。

于 2021-06-09T09:43:44.377 回答