windows - 代码段描述符中的 D 标志对 x86-64 指令有什么作用?
问题描述
我试图了解D flag
在 x86-64 代码中使用时代码段描述符中的工作原理。它设置在D/B
代码段描述符的第 22 位,如下图所示:
英特尔文档(来自第3.4.5 节段描述符)声明如下:
D/B(默认操作大小/默认堆栈指针大小和/或上限)标志
根据段描述符是可执行代码段、向下扩展数据段还是堆栈段执行不同的功能。(对于 32 位代码和数据段,该标志应始终设置为 1,对于 16 位代码和数据段,该标志应始终设置为 0。)
• 可执行代码段。该标志称为 D 标志,它指示段中指令引用的有效地址和操作数的默认长度。如果设置了标志,则假定 32 位地址和 32 位或 8 位操作数;如果清楚,则假定 16 位地址和 16 位或 8 位操作数。指令前缀 66H 可用于选择默认以外的操作数大小,前缀 67H 可用于选择默认以外的地址大小。
所以我试图了解它会影响哪些 x86-64 指令以及如何影响?
PS。当我尝试通过设置该位来运行一些测试(在 Windows 内核中)时,操作系统会立即出现三倍故障。
解决方案
如果L
为代码段描述符设置了(长模式),则D
必须清除。L=1 / D=1 组合目前无意义/保留。英特尔在您正在查看的同一文档中记录了这一点。
如果L
清除,则D
在 16 位和 32 位模式之间进行选择。(即默认操作数/地址大小)。是的,存在 16 位保护模式,但不,没有人使用它。
默认地址/操作数大小只有 3 种可能性:
- 16 位模式(real、vm86、protected):默认地址和操作数大小 = 16 位
- 32 位保护模式:默认地址和操作数大小 = 32 位
- 64 位模式:默认地址大小 = 64 位,默认操作数大小 = 32 位
没有 16 个 64 位寄存器的选项,但默认操作数大小为 16 位或 64 位。或 32 位的默认地址大小可覆盖为 64。
推荐阅读
- mongodb - 具有多个字段的Spring数据mongoDB推送操作不起作用
- mysql - Mysql 使用内部连接数据多次更新数据
- javascript - 在 v-for 循环中记住上传时的图像位置
- ssh - sudo over ssh - 不接受密码时卡住
- vue.js - 如何在 VueJS 中使用 ThreeJS
- c# - 从 C# MVC 实体框架中的数据库 onclick 中删除条目
- java - android.view.InflateException: Binary XML file line #99: Binary XML file line #99: Error inflating class android.widget.ProgressBar
- xamarin - 如何制作带有文本中心的圆形进度条
- azure - 一次调用检索存储库列表及其标签版本
- nginx - docker push 到 Kubernetes 集群内的私有 Docker 注册表失败,并显示:413 Request Entity Too Large