为什么带-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 eax
,edx:eax
将被解释为 64 位有符号数:
在您的情况下,这将是 0x00000000fffffffb,即 4294967291(而不是 -5)。
div
和idiv
两种情况会导致异常:
- 你除以零
- 除法结果不在
eax
寄存器可以表示的范围内
eax
可以保存 -2147483648 到 +2147483647 范围内的有符号数,但 -4294967291 超出该范围。你会得到一个例外。
should not cause an FPE.
确实,div
和 idiv
会导致 "integer division exception",而不是 "a floating-point exception"。
然而,许多操作系统会显示消息"floating point exception"; POSIX 将 SIGFPE 定义为涵盖任何算术异常。
据我了解,idiv %ebx
会将 edx:eax
(按此顺序连接成 64 位值)与 32 位 ebx
。
但是,当我尝试将 0x00000000:0xfffffffb
(0 和 -5)除以 0xffffffff
(-1)时,出现浮点异常。
谁能解释一下为什么?我很困惑为什么会这样,因为我毕竟不是除以 0。
注意,我知道我需要签名扩展edx:eax
来实现我想要的,即计算-5/-1
。但是,即使没有符号扩展,下面也应该
不会导致 FPE。
当我在寻找sign-extend edx:eax
的方法时,我在等待这个问题的答案时,无意中找到了答案。
如 -1
导致商溢出。
解决方案是 sign-extend 使用 cdq
指令,而不是将 %edx
.
Note that I know I need to sign extend
edx:eax
...
如果您不sign-extend eax
,edx:eax
将被解释为 64 位有符号数:
在您的情况下,这将是 0x00000000fffffffb,即 4294967291(而不是 -5)。
div
和idiv
两种情况会导致异常:
- 你除以零
- 除法结果不在
eax
寄存器可以表示的范围内
eax
可以保存 -2147483648 到 +2147483647 范围内的有符号数,但 -4294967291 超出该范围。你会得到一个例外。
should not cause an FPE.
确实,div
和 idiv
会导致 "integer division exception",而不是 "a floating-point exception"。
然而,许多操作系统会显示消息"floating point exception"; POSIX 将 SIGFPE 定义为涵盖任何算术异常。