英特尔的64位IDT门描述符中有一个段选择器。但是,根据我对5部分英特尔手册的理解,中断处理程序的线性地址从IDT门描述符中指定的64位偏移量加载到RIP中。
段选择器的唯一用途是检查:
我的问题是:
非常感谢提前!
答案 0 :(得分:6)
如果我正确地解释了这一点,根据英特尔手册,x64不使用分段。我阅读AMD's System programming for AMD64来理解这一点,因为我发现他们的解释更容易理解,因为他们明确地处理x86_64(他们确实发明了它,我想);他们说:
在长模式下,分段的效果取决于处理器是否在兼容性方面运行 模式或64位模式:
- 在兼容模式下,分段功能与传统模式一样,使用传统的16位或32位保护模式语义。
- 64位模式,禁用分段,创建平坦的64位虚拟地址空间。可以看出,某些功能有些 段寄存器,特别是系统段寄存器,继续 在64位模式下使用。
具体来说,查看4.8节长模式段描述符。回答你的第二个问题:
在64位模式下忽略的字段。在64位中禁用分段 模式,代码段跨越所有虚拟内存。在此模式下,将忽略代码段基址。出于虚拟地址计算的目的,基址被视为值为零。
解释:因为x86_64中的“段”是整个地址空间,除了0之外,基址没有意义,因为偏移都是绝对的(相对于0)。
因此,这将回答我认为的第一个问题 - RIP被视为64位偏移值。从同一章的门描述符页面:
在长模式下,门描述符扩展64位,允许它们保持64位偏移。
在处理数据段时会变得更复杂:
FS和GS段寄存器引用的数据段以64位进行特殊处理 模式。对于这些段,不忽略基址字段,并且可以使用非零值 在虚拟地址计算中。可以使用模型指定64位的段基地址 - 特定登记册。有关更多信息,请参见第70页的“64位模式下的FS和GS寄存器”。
该部分说明:
64位模式下的FS和GS寄存器。与CS,DS,ES和SS段不同,FS和GS 段覆盖可以在64位模式下使用。当在64位中使用FS和GS段覆盖时 模式,它们各自的基地址用于有效地址(EA)计算。完整的 EA计算然后变为(FS或GS).base + base +(scale * index)+ displacement。 FS.base GS.base值也扩展为完整的64位虚拟地址大小,如图4-5所示。 允许生成的EA计算包含正负地址。
在64位模式下,不会检查FS段和GS段覆盖的限制或属性。代替, 处理器检查所有虚拟地址引用是否为规范形式。
换句话说,虽然只检查了分段的形式,但数据段可以像分段一样使用,而不是检查访问形式是否位于段的范围内。
我认为这是正确的解释;但是,更正/指针非常受欢迎。