在使用DIV指令之前为什么EDX应该为0?
我注意到当EDX包含一些像00401000这样的随机默认值,然后我使用这样的DIV指令:
mov eax,10 mov ebx,5 div ebx
它会导致INTEGER溢出错误。 但是,如果我将edx
设置为0,并执行相同的操作。 我相信使用div
会导致商覆盖eax
和其余覆盖edx
。
得到这个INTEGER OVERFLOW错误真的让我困惑。
对于DIV
,寄存器EDX
和EAX
形成一个单一的64位值(通常显示为EDX:EAX
),在这种情况下, EBX
被分割。
所以如果EAX
= 10
或者hexA
和EDX
是20
或者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
。
(或者对于有签署的部门, cdq
在idiv
之前签署将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设置为零,你使用的值就会变得非常大。
信任,帮助