我试图在x86-64代码中使用时,在代码段描述符中了解D flag
的工作原理。设置在代码段描述符的D/B
位22中,如下图所示:
英特尔文档(来自3.4.5 Segment Descriptors部分)指出:
D / B(默认操作大小/默认堆栈指针大小和/或上位 绑定)标志
根据段是否执行不同的功能 描述符是可执行代码段,扩展数据段, 或堆栈段。 (对于32位,此标志应始终设置为1 代码和数据段,对于16位代码和数据段则为0。)
•可执行代码段。该标志称为D标志,它 指示有效地址和操作数的默认长度 该段中的说明所引用。如果设置了标志,则为32位 假定地址和32位或8位操作数;如果很清楚 假定使用16位地址和16位或8位操作数。的 指令前缀66H可用于选择其他大小的操作数 而不是默认值,并且可以使用前缀67H选择地址 大小不是默认值。
所以我试图了解它会影响哪些x86-64指令以及如何影响?
PS。当我尝试通过将该位设置为打开来运行某些测试(在Windows内核中)时,操作系统会立即将故障增加三倍。
答案 0 :(得分:4)
如果为代码段描述符设置了L
(长模式),则必须清除D
。 L = 1 / D = 1组合当前是无意义的/保留的。英特尔会在您正在查看的同一文档中对此进行记录。
如果清除L
,则D
在16位和32位模式之间进行选择。 (即默认操作数/地址大小)。是的,存在16位保护模式,但是不,没有人使用它。
默认地址/操作数大小只有3种:
没有选项可以具有16个64位寄存器,但默认操作数大小为16位或64位。或默认的32位地址大小可覆盖为64。