Search code examples
assemblyx86gnu-assembleratt

Why IDIV with -1 causes floating point exception?


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.

gdb screenshot


Solution

  • 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.