IA-32e 64位IDT门描述符

Ver*_*ern 8 assembly operating-system x86-64 intel

英特尔的64位IDT门描述符中有一个段选择器.但是,根据我对5部分英特尔手册的理解,中断处理程序的线性地址从IDT门描述符中指定的64位偏移量加载到RIP中.

段选择器的唯一用途是检查:

  1. 如果权限级别有变化
  2. 中断处理程序真正指向代码段

我的问题是:

  1. RIP仅取自64位偏移量吗?或者RIP =偏移(符号扩展到64位)+段选择器基数?
  2. IDT门描述符中的段选择器指向的基址是否被忽略?或者它有用吗?

提前谢谢了!

小智 6

如果我正确地解释这个,根据intel手册,x64不使用分段.我阅读AMD的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寄存器".

该部分指出:

FS和GS寄存器采用64位模式.与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段覆盖的限制或属性.相反,处理器检查所有虚拟地址引用是否为规范形式.

换句话说,数据段可以像使用分段一样,尽管只检查分段的形式,而不是检查访问的形式是否在段的边界内.

我认为这是正确的解释; 但是,更正/指针非常赞赏.

  • @ this.josh:我不同意:80386的所有Intel和AMD处理器,包括最新的处理器,_do_支持32位模式中指定的分段._Operating Systems_选择不使用段,至少在大多数情况下(在32位x86上,使用Linux,`gs`段寄存器用于实现线程本地存储).因此,对于具有非零基址的段寄存器的支持在最近的处理器中没有得到彻底优化 - 但它仍然有效. (2认同)