据我了解,idiv %ebx
将edx:eax
(按该顺序连接为64位值)与32位ebx
相除。
但是,当我尝试将0x00000000:0xfffffffb
(-1)与0xffffffff
(0和-5)分开时,会出现浮点异常。
有人可以解释为什么吗?我很困惑为什么会这样,因为我毕竟没有被0除。
注意,我知道我需要对扩展名edx:eax
进行签名才能实现我想要的目标,即计算-5/-1
。但是,即使没有符号扩展名,以下内容也应
不会导致FPE。
答案 0 :(得分:4)
请注意,我知道我需要签署扩展
edx:eax
...
如果不对eax
进行符号扩展,则edx:eax
被解释为64位带符号数字:
在您的情况下,该值为0x00000000fffffffb,即4294967291(而不是-5)。
div
和idiv
在两种情况下会导致异常:
eax
寄存器可以表示的范围内 eax
可以保留从-2147483648到+2147483647范围内的带符号数字,但是-4294967291不在该范围内。您会得到一个例外。
不应引起FPE。
实际上,div
和idiv
会导致“整数除法异常”,而不是“浮点异常”。
但是,许多操作系统将显示“浮点异常”消息; POSIX将SIGFPE定义为涵盖任何算术异常。
答案 1 :(得分:2)
在等待答案的过程中,我一直在寻找一种扩展edx:eax
的方式,所以我自己偶然找到了答案。
如in this answer所示,事实证明,所有除法错误(包括除法商溢出时)都会引发FPE(浮点异常)。链接的答案还说,通常只有-1
会导致这种商溢出。
解决方案是使用cdq
指令对符号进行扩展,而不是将%edx
清零。