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

时间:2019-05-25 08:52:52

标签: assembly x86 gas att

据我了解,idiv %ebxedx:eax(按该顺序连接为64位值)与32位ebx相除。

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

有人可以解释为什么吗?我很困惑为什么会这样,因为我毕竟没有被0除。


注意,我知道我需要对扩展名edx:eax进行签名才能实现我想要的目标,即计算-5/-1。但是,即使没有符号扩展名,以下内容也应 不会导致FPE。

gdb screenshot

2 个答案:

答案 0 :(得分:4)

  

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

如果不对eax进行符号扩展,则edx:eax被解释为64位带符号数字:

在您的情况下,该值为0x00000000fffffffb,即4294967291(而不是-5)。

dividiv在两种情况下会导致异常:

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

eax可以保留从-2147483648到+2147483647范围内的带符号数字,但是-4294967291不在该范围内。您会得到一个例外。

  

不应引起FPE。

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

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

答案 1 :(得分:2)

在等待答案的过程中,我一直在寻找一种扩展edx:eax的方式,所以我自己偶然找到了答案。

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

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