温馨提示:本文翻译自stackoverflow.com,查看原文请点击:assembly - movzx and cwd
assembly x86

assembly - movzx和cwd

发布于 2020-04-08 00:11:24

我有以下两个代码段:

mov ax, word [wNum2]
cwd
div word [wNum3]
mov [wAns16], dx
movzx eax, word [wNum2]
;cwd
div word [wNum3]
mov [wAns16], edx

第一个会给出正确的答案,第二个会给我一个大约一百左右的答案,除非我取消对cwd的注释。

我的问题是我认为movzx会为我将所有内容归零,这将使cwd不再需要。我是否完全误解了它们的工作原理?有人可以引导我浏览这些代码片段吗?

查看更多

提问者
zapshe
被浏览
71
zx485 2020-02-01 11:38

裸结果可以相等还是不相等-取决于值。CWD状态的描述

通过符号扩展将寄存器AX,EAX或RAX中操作数的大小加倍(取决于操作数大小),并将结果分别存储在寄存器DX:AX,EDX:EAX或RDX:RAX中。CWD指令将AX寄存器中值的符号(位15)复制到DX寄存器中的每个位位置。

因此,如果in的值AX小于32,767(最大15位),则其结果等效于MOVZX(零扩展)和MOVSX(符号扩展)。但是,如果该值更大,则等于MOVSX通常MOVZX将与DIV(无符号除法)结合使用,并与(有符号除法)MOVSX结合使用IDIV

但是仍然存在将结果存储在何处的问题:
CWD将32位结果存储在两个16位寄存器中DX:AX,而MOV?X指令将其存储在32位寄存器中EAX

这对以下DIV指令有影响。代码的第一部分使用32位值DX:AX作为输入,而第二种方法假定EAX为16位的输入DIV

F7 /6   DIV r/m16   M   Valid   Valid   Unsigned divide DX:AX by r/m16, with result stored in AX ← Quotient, DX ← Remainder. 

这使得结果不可预测,因为它DX是不确定的,并且EAX除法的上半部分未被使用。