【问题标题】: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)。
div和idiv会在两种情况下引发异常:
eax 可以保存从 -2147483648 到 +2147483647 范围内的有符号数,但 -4294967291 不在该范围内。你会得到一个例外。
不应导致 FPE。
确实,div 和 idiv 会导致“整数除法异常”,而不是“浮点异常”。
但是,许多操作系统会显示“浮点异常”消息; POSIX 将 SIGFPE 定义为涵盖任何算术异常。
【解决方案2】:
当我在等待这个问题的答案时,我正在寻找一种签名扩展edx:eax 的方法,我自己不小心找到了答案。
正如in this answer 所指出的,事实证明,所有除法错误都会引发 FPE(浮点异常),包括除法商溢出时。链接的答案还说,通常只有-1 会导致这个商溢出。
解决方案是使用cdq 指令进行符号扩展,而不是将%edx 归零。