在使用DIV指令之前为什么EDX应该为0?

我注意到当EDX包含一些像00401000这样的随机默认值,然后我使用这样的DIV指令:

mov eax,10 mov ebx,5 div ebx 

它会导致INTEGER溢出错误。 但是,如果我将edx设置为0,并执行相同的操作。 我相信使用div会导致商覆盖eax和其余覆盖edx

得到这个INTEGER OVERFLOW错误真的让我困惑。

对于DIV ,寄存器EDXEAX形成一个单一的64位值(通常显示为EDX:EAX ),在这种情况下, EBX被分割。

所以如果EAX = 10或者hexAEDX20或者hex14 ,那么它们一起构成一个64位的hex值14 0000 000A或者十进制的85899345930 。 如果这除以5 ,结果是17179869186或hex4 0000 0002这是一个不适合32位的值

这就是为什么你得到一个整数溢出。

但是,如果EDX只有1 ,那么可以将hex数1 0000 000A除以5 ,结果是hex数3333 3335 。 这不是你想要的值,但它不会导致整数溢出。

为了真正将32位寄存器EAX除以另一个32位寄存器,请注意由EDX:EAX形成的64位值的顶部为0

所以, 一个单独的分区之前 ,你通常应该把EDX设置为0

(或者对于有签署的部门, cdqidiv之前签署将EAX扩展到EDX:EAX


EDX并不总是必须为0 。 结果导致溢出可能不那么大。

BigInteger代码中的一个例子:

在与DIV划分之后,商在EAX ,其余的在EDX 。 要将BigInteger (包含许多DWORDS数组)的东西除以10 (例如,将该值转换为十进制string),请执行以下操作:

  ; ECX contains number of "limbs" (DWORDs) to divide by 10 XOR EDX,EDX MOV EBX,10 LEA ESI,[EDI + 4*ECX - 4] ; now points to top element of array @DivLoop: MOV EAX,[ESI] DIV EBX ; divide EDX:EAX by EBX. After that, ; quotient in EAX, remainder in EDX MOV [ESI],EAX SUB ESI,4 ; remainder in EDX is re-used as top DWORD... DEC ECX ; ... for the next iteration, and is NOT set to 0. JNE @DivLoop 

在该循环之后,由整个数组(即由BigInteger )表示的值除以10 ,并且EDX包含该除法的其余部分。

FWIW,在我的汇编程序中,以@开始的标号是函数的局部,即它们不会干扰其他函数中同名的标号。

DIV指令将DX指令后面的r / m32除以EDX:EAX。 所以,如果你不能把EDX设置为零,你使用的值就会变得非常大。

信任,帮助