只有 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 程序的其他示例无论如何都不包含此指令,因此它可能根本不应该存在。