为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

繁花不似锦 2019-06-27 15:48:20

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

当edX包含像00401000这样的随机默认值时,我注意到,然后我使用了如下所示的dIV指令:

mov eax,10
mov ebx,5
div ebx

它会导致整数溢出错误。但是,如果我edx做同样的事情。我相信用div会导致商覆盖eax其余的覆盖edx.

得到这个整数溢出错误真的让我很困惑。


查看完整描述

2 回答

?
哈士奇WWW

做什么

对于32位/32位=>32位除法:零或符号-将32位红利从EAX扩展到64位edX:EAX.
对于16位,ax到dx:ax与cwd或者是Xor-零。

  • 未签署:

    XOR EDX,EDX

    然后

    DIV divisor

  • 签署:

    CDQ

    然后

    IDIV divisor

另见我们什么时候和为什么在mul/div中签署扩展和使用cdq?


(TL;DR)

DIV,登记册EDXEAX表单一个64位值(通常显示为EDX:EAX),在这种情况下,它被划分为EBX.

所以如果EAX = 10或妖术AEDX是,说20或妖术14,然后它们一起形成64位值十六进制。14 0000 000A或十进制85899345930..如果这除以5,结果是17179869186或妖术
4 0000 0002它是一个不适合32位的值。.

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

但是,如果,EDX1,你会除以妖术1 0000 000A通过5,这导致了十六进制
3333 3335..这不是您想要的值,但它不会导致整数溢出。

真正除以32位寄存器EAX通过另一个32位寄存器,注意64位值的顶部由EDX:EAX0.

所以,以前一个部门,你应该一般EDX0.

(或签署的分部,cdq签延EAXEDX: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的内置汇编程序)中,标签以@是函数的局部,即它们不干扰其他函数中的同名标签。


查看完整回答
反对 回复 2019-06-27
?
慕容3067478

DIV指令将edX:EAX除以跟随DIV指令的r/m32。因此,如果您没有将edX设置为零,则所使用的值会变得非常大。

信任,帮助


查看完整回答
反对 回复 2019-06-27
  • 2 回答
  • 0 关注
  • 353 浏览
我要回答

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信