为什么带-1 的 IDIV 会导致浮点异常?

Why IDIV with -1 causes floating point exception?

据我了解,idiv %ebx 会将 edx:eax(按此顺序连接成 64 位值)与 32 位 ebx

但是,当我尝试将 0x00000000:0xfffffffb(0 和 -5)除以 0xffffffff(-1)时,出现浮点异常。

谁能解释一下为什么?我很困惑为什么会这样,因为我毕竟不是除以 0。


注意,我知道我需要签名扩展edx:eax来实现我想要的,即计算-5/-1。但是,即使没有符号扩展,下面也应该 不会导致 FPE。

当我在寻找sign-extend edx:eax的方法时,我在等待这个问题的答案时,无意中找到了答案。

所示,事实证明 FPE(floating-point 异常)在所有 divide-errors 上引发,包括除法商溢出时。链接的答案还说通常只有 -1 导致商溢出。

解决方案是 sign-extend 使用 cdq 指令,而不是将 %edx.

归零

Note that I know I need to sign extend edx:eax ...

如果您不sign-extend eaxedx:eax 将被解释为 64 位有符号数:

在您的情况下,这将是 0x00000000fffffffb,即 4294967291(而不是 -5)。

dividiv两种情况会导致异常:

  • 你除以零
  • 除法结果不在eax寄存器可以表示的范围内

eax 可以保存 -2147483648 到 +2147483647 范围内的有符号数,但 -4294967291 超出该范围。你会得到一个例外。

should not cause an FPE.

确实,dividiv 会导致 "integer division exception",而不是 "a floating-point exception"。

然而,许多操作系统会显示消息"floating point exception"; POSIX 将 SIGFPE 定义为涵盖任何算术异常。