只有 EAX 的低半部分被置零? (MASM 使用 .486 / .model flat,stdcall)
Only the low half of EAX is zeroed? (MASM using .486 / .model flat,stdcall)
运行 下面的代码在 VS2019 中,令我惊讶的是寄存器 EAX 没有用指令 xor eax, eax
.
归零
_text SEGMENT
.486
.model flat,stdcall
.stack 4096
.code
main PROC
xor eax, eax
ret
main ENDP
_text ENDS
END
P.S.: 我期望 EAX 寄存器在指令 xor eax, eax
之后为零。在 ret
指令中使用断点调试代码 我可以在寄存器 window 中看到只有 AX 被置零。 EAX 中的 16-31 位没有任何变化。在 x64 中,指令 xor eax, eax
正确执行,按预期将整个 RAX 寄存器清零。
根据您的意见,SEGMENT
指令似乎以某种方式说服了汇编器它正在将代码汇编为 运行 16 位模式。
在 16 位模式下,像 eax
这样操作 32 位寄存器的指令需要一个 66
ope运行d-size 前缀,所以汇编程序发出 66 33 C0
.然而,该程序实际上 运行 在 32 位模式下,其中 66
ope运行d-size 前缀的含义是相反的:32 位 ope运行ds是默认值,66
选择 16 位 ope运行ds。所以当程序运行时,指令执行为xor ax, ax
并且没有将eax
.
的高位清零
您说删除 SEGMENT
指令可以解决问题。我不知道它为什么会产生这种效果,但 32 位 MASM 程序的其他示例无论如何都不包含此指令,因此它可能根本不应该存在。
运行 下面的代码在 VS2019 中,令我惊讶的是寄存器 EAX 没有用指令 xor eax, eax
.
_text SEGMENT
.486
.model flat,stdcall
.stack 4096
.code
main PROC
xor eax, eax
ret
main ENDP
_text ENDS
END
P.S.: 我期望 EAX 寄存器在指令 xor eax, eax
之后为零。在 ret
指令中使用断点调试代码 我可以在寄存器 window 中看到只有 AX 被置零。 EAX 中的 16-31 位没有任何变化。在 x64 中,指令 xor eax, eax
正确执行,按预期将整个 RAX 寄存器清零。
根据您的意见,SEGMENT
指令似乎以某种方式说服了汇编器它正在将代码汇编为 运行 16 位模式。
在 16 位模式下,像 eax
这样操作 32 位寄存器的指令需要一个 66
ope运行d-size 前缀,所以汇编程序发出 66 33 C0
.然而,该程序实际上 运行 在 32 位模式下,其中 66
ope运行d-size 前缀的含义是相反的:32 位 ope运行ds是默认值,66
选择 16 位 ope运行ds。所以当程序运行时,指令执行为xor ax, ax
并且没有将eax
.
您说删除 SEGMENT
指令可以解决问题。我不知道它为什么会产生这种效果,但 32 位 MASM 程序的其他示例无论如何都不包含此指令,因此它可能根本不应该存在。