问题
As far as I understood, idiv %ebx
will divide edx:eax
(concatenated into 64-bit value, in that order) with 32-bit ebx
.
However, when I try to divide 0x00000000:0xfffffffb
(0 and -5) with 0xffffffff
(-1), I get a floating-point exception.
Can someone explain why? I'm quite puzzled why this is happening because I'm not dividing by 0 after all.
Note that I know I need to sign extend edx:eax
to achieve what I want, which is to calculate -5/-1
. However, even without sign extension the below should
not cause an FPE.
回答1:
Note that I know I need to sign extend
edx:eax
...
If you don't sign-extend eax
, edx:eax
is interpreted as 64-bit signed number:
In your case, this would be 0x00000000fffffffb which is 4294967291 (and not -5).
div
and idiv
will cause an exception in two cases:
- You divide by zero
- The division result is not in the range that can be represented by the
eax
register
eax
can hold signed numbers in the range from -2147483648 to +2147483647, but -4294967291 lies outside that range. You'll get an exception.
should not cause an FPE.
Indeed, div
and idiv
will cause an "integer division exception", not "a floating-point exception".
However, many OSs will show the message "floating point exception"; POSIX defines SIGFPE as covering any arithmetic exception.
回答2:
As I was looking for a way to sign-extend edx:eax
while I was waiting for an answer to this question, I accidentally found the answer myself.
As indicated in this answer, it turns out FPE (floating-point exception) is raised on all divide-errors, including when quotient of division overflows. The linked answer also says that usually, only -1
causes this quotient overflow.
The solution is to sign-extend with cdq
instruction, instead of zeroing out %edx
.
来源:https://stackoverflow.com/questions/56303282/why-idiv-with-1-causes-floating-point-exception