Assembly Bochs GDT段限制在十六进制中向左移动3次,并添加0xFFF。这正常吗?

Assembly Bochs GDT段限制在十六进制中向左移动3次,并添加0xFFF。这正常吗?,assembly,x86,osdev,bochs,gdt,Assembly,X86,Osdev,Bochs,Gdt,我目前正在为我的引导加载程序设置GDT。我有3(4)部分: (零段) 4GB内核代码段 4GB内核数据段 2GB堆栈数据部分(我在截图时忘了将1位设置为0。稍后这将是1mb) 以下是我设置GDT的代码: 7 ; GDT null segment 8 gdt_null: 9 dq 0x00 10 11 ; GDT code segment (4GB) 12 gdt_code: 13 dw 0xFFFF 14 dw 0x00 15 db

我目前正在为我的引导加载程序设置GDT。我有3(4)部分:

  • (零段)
  • 4GB内核代码段
  • 4GB内核数据段
  • 2GB堆栈数据部分(我在截图时忘了将1位设置为0。稍后这将是1mb)
以下是我设置GDT的代码:

  7 ; GDT null segment
  8 gdt_null:
  9     dq 0x00
 10 
 11 ; GDT code segment (4GB)
 12 gdt_code:
 13     dw 0xFFFF
 14     dw 0x00
 15     db 0x00
 16     db 10011010b
 17     db 11001111b
 18     db 0x00
 19 
 20 ; GDT data segment (4GB)
 21 gdt_data:
 22     dw 0xFFFF
 23     dw 0x00
 24     db 0x00
 25     db 10010010b
 26     db 11001111b
 27     db 0x00                                                                                          
 28 
 29 ; Extra segmet for stack
 30 ; Preventing bufferoverflows from stack could write into other data
 31 ; Size is 1M (0x100 * 4kb) startting from base 7e00 (512 bytes after 7c00)
 32 gdt_stack:
 33     dw 0x0100
 34     dw 0x7e00
 35     db 0x00
 36     db 10010010b
 37     db 11001000b
 38     db 0x00

但当我将二进制文件加载到bochs中时,它会给出以下结果:

完全按照我定义加载到内存中的字节:

在这里,我意识到每次都会将0xFFF添加到段中。这是因为我使用4kb作为粒度吗


当我选择0xFF作为4kb粒度的大小时,这将扩展到0xFFFFF,因此我只能使段1mb-1字节大?

是的,这是因为您在GDT条目中使用4kb粒度。根据第5.3节限制检查:

当G标志清除(字节粒度)时,有效限制为段中20位限制字段的值 描述符。在这里,限制范围从0到FFF H(1兆字节)设置G标志时(4-KByte页面粒度), 处理器将限制字段中的值按2^12(4千字节)的系数进行缩放。。在这种情况下,有效极限范围 从FFFH(4千字节)到FFFFFFH(4千字节)。请注意,当使用缩放(设置了G标志)时 未对照限制检查段偏移量(地址);例如,请注意,如果段限制为0, 偏移量0到FFFH仍然有效

从中,LSL指令描述了所使用的机制,并描述了您在BOCHS中看到的行为:

段限制是一个20位的值,包含在段的字节0和1以及字节6的前4位中 描述符。如果描述符具有字节粒度段限制(粒度标志设置为0),则目标 使用字节粒度值(字节限制)加载操作数如果描述符有页面粒度段限制( 粒度标志设置为1),LSL指令将页面粒度限制(页面限制)转换为字节限制 在将其加载到目标操作数之前通过将20位“原始”限制向左移动12来执行转换 位,并用1填充低位12位。


当我选择0xFF作为4kb粒度的大小时,您问了这样一个问题:这会扩展到0xFFFFF吗,所以我只能使段1mb-1字节大。对于页面粒度,0xFF段限制向左移动12位,产生0xFF000,低12位设置为1。结果是0xFFFFF字节的实际限制。此限制允许从指定的基址寻址满1MiB的内存,即0到0xFFFFF(包括0xFFFFF)。如果希望段具有特定的字节大小(介于0x00000和0xFFFFF之间),可以使用字节粒度。可以用不同的粒度定义描述符。

这实际上是限制,而不是大小。但是是的,这是因为页面粒度。