我注意到EDX包含一些随机默认值,如00401000,然后我使用这样的DIV指令:
mov eax,10
mov ebx,5
div ebx
导致INTEGER OVERFLOW ERROR。但是,如果我将edx
设置为0并执行相同的操作。我相信使用div
会导致商覆盖eax
,其余覆盖edx
。
获得此INTEGER OVERFLOW ERROR确实让我感到困惑。
答案 0 :(得分:7)
对于32位/ 32位=> 32位除法:将32位被从EAX归零或符号扩展为64位EDX:EAX。
对于16位,AX进入DX:具有cwd
或xor-zeroing的AX。
XOR EDX,EDX
然后DIV divisor
CDQ
然后IDIV divisor
另见When and why do we sign extend and use cdq with mul/div?
对于DIV
,寄存器EDX
和EAX
形成一个64位的值(通常显示为EDX:EAX
),然后将其划分,在本例中为EBX
。
因此,如果EAX
= 10
或十六进制A
和EDX
是20
或十六进制14
,那么它们一起形成64位值十六进制14 0000 000A
或十进制85899345930
。如果除以5
,则结果为17179869186
或十六进制
4 0000 0002
,这是一个不适合32位的值。
这就是你得到整数溢出的原因。
但是,如果EDX
仅为1
,则您可以将1 0000 000A
除以5
,这会产生十六进制为3333 3335
。这不是您想要的值,但它不会导致整数溢出。
要真正将32位寄存器EAX
除以另一个32位寄存器,请注意EDX:EAX
形成的64位值的顶部为0
。
所以,之前一个部门,你应该 将EDX
设置为0
。
(或者对于已签名的部门,cdq
在EAX
之前将EDX:EAX
扩展为idiv
但EDX
并非总是0
。结果导致溢出可能不会那么大。
我的BigInteger
代码中的一个示例:
在使用DIV
进行除法后,该商位于EAX
,余数位于EDX
。要将BigInteger
(由DWORDS
组成的数组10
除以 ; ECX contains number of "limbs" (DWORDs) to divide by 10
XOR EDX,EDX ; before start of loop, set EDX to 0
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,在我使用的汇编程序(Delphi的内置汇编程序)中,以...
gem 'sweet-alert'
gem 'sweet-alert-confirm'
...
开头的标签是函数的本地标签,即它们不会干扰同名其他功能中的标签。
答案 1 :(得分:1)
DIV指令将EDX:EAX除以DIV指令后面的r / m32。因此,如果您未能将EDX设置为零,则您使用的值将变得非常大。
信任帮助