代码段描述符中的 D 标志对 x86-64 指令有何作用?

What does the D flag in the code segment descriptor do for x86-64 instructions?

我试图了解代码段描述符中 D flag 在 x86-64 代码中使用时的工作原理。它设置在代码段描述符的 D/B 位 22 中,如下图所示:

英特尔文档(来自 3.4.5 Segment Descriptors 部分)说明如下:

D/B (default operation size/default stack pointer size and/or upper bound) flag

Performs different functions depending on whether the segment descriptor is an executable code segment, an expand-down data segment, or a stack segment. (This flag should always be set to 1 for 32-bit code and data segments and to 0 for 16-bit code and data segments.)

• Executable code segment. The flag is called the D flag and it indicates the default length for effective addresses and operands referenced by instructions in the segment. If the flag is set, 32-bit addresses and 32-bit or 8-bit operands are assumed; if it is clear, 16-bit addresses and 16-bit or 8-bit operands are assumed. The instruction prefix 66H can be used to select an operand size other than the default, and the prefix 67H can be used select an address size other than the default.

所以我想了解它会影响哪些 x86-64 指令以及如何影响?

PS。当我尝试通过设置该位来 运行 某些测试(在 Windows 内核中)时,OS 立即出现三重故障。

如果为代码段描述符设置L(长模式),则D必须清除。 L=1 / D=1 组合目前无意义/保留。英特尔在您正在查看的同一文档中对此进行了附近的记录。

如果 L 被清除,则 D 在 16 位和 32 位模式之间选择。 (即默认操作数/地址大小)。是的,16 位保护模式存在,但没有,没有人使用它。


默认只有3种可能address/operand-size:

  • 16 位模式(真实、vm86、受保护):默认地址和操作数大小 = 16 位
  • 32 位保护模式:默认地址和操作数大小 = 32 位
  • 64 位模式:默认地址大小 = 64 位,默认操作数大小 = 32 位

没有 16x 64 位寄存器的选项,但默认操作数大小为 16 位或 64 位。或者默认地址大小为 32 位,可覆盖为 64。