【问题标题】:Why IDIV with -1 causes floating point exception?为什么带有-1的IDIV会导致浮点异常?
【发布时间】:2019-05-25 08:52:51
【问题描述】:

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

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

有人能解释为什么吗?我很困惑为什么会发生这种情况,因为我毕竟没有除以 0。


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

【问题讨论】:

标签: assembly x86 gnu-assembler att


【解决方案1】:

请注意,我知道我需要签署extend edx:eax ...

如果您不对eax 进行符号扩展,edx:eax 将被解释为 64 位有符号数:

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

dividiv会在两种情况下引发异常:

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

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

不应导致 FPE。

确实,dividiv 会导致“整数除法异常”,而不是“浮点异常”。

但是,许多操作系统会显示“浮点异常”消息; POSIX 将 SIGFPE 定义为涵盖任何算术异常。

【讨论】:

    【解决方案2】:

    当我在等待这个问题的答案时,我正在寻找一种签名扩展edx:eax 的方法,我自己不小心找到了答案。

    正如in this answer 所指出的,事实证明,所有除法错误都会引发 FPE(浮点异常),包括除法商溢出时。链接的答案还说,通常只有-1 会导致这个商溢出。

    解决方案是使用cdq 指令进行符号扩展,而不是将%edx 归零。

    【讨论】:

      猜你喜欢
      • 2016-06-30
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多