1

Is there a program transformation or compilation technique that removes potential runtime exceptions such as div by 0, floating point overflow / underflow, etc. I want to handle potential exceptions in my program before the CPU generates them. Furthermore, I'd like a transformation expressed at the x64 machine code level.

For instance, to remove the possibility of CPU generating div by 0, I can check that divisor is 0 before invoking the div instruction, something along the following lines.

cmp rcx 0
jz my_handler //some routine I wrote
div rcx

However, it is not clear how to implement this technique for floating point exceptions, especially underflow and overflow. Wouldn't the check for overflow cause the overflow itself? I realize that languages support exception handling, but my use case necessitates this.

rsinha
  • 2,167
  • 3
  • 18
  • 17
  • 3
    Just set the exception mask bits in MXCSR, however under normal circumstances they are already set so this problem usually doesn't exist. – harold Oct 12 '16 at 15:52
  • 2
    The only normal source of SIGFPE exceptions from normally-compiled programs is ironically integer division. You just get NaN or +/-Inf instead of an exception from FP ops, because as harold says all FP exceptions are masked by default. Compilers don't make code that can produce divide overflow, but division by zero still needs to be avoided. (http://stackoverflow.com/questions/37262572/on-which-platforms-does-integer-divide-by-zero-trigger-a-floating-point-exceptio) – Peter Cordes Oct 12 '16 at 16:26
  • 1
    BTW, that's not how DIV's operands work: http://www.felixcloutier.com/x86/DIV.html – Peter Cordes Oct 12 '16 at 16:27
  • Thanks for your responses. But it seems that the OS gets to decide how to handle FP exceptions, and (according to your response), only the integer division leads to SIGFPE. Is it possible to have CPU not even generate the FP exceptions (#MF and #XM in x86-64)? Perhaps the exception mask bits suggested by @harold will work? – rsinha Oct 12 '16 at 18:49
  • Furthermore, if I want to handle all division exceptions (#DE), would it suffice to check two cases: 1) divisor is not 0, and 2) divisor and dividend are not -1 and INT_MIN, respectively? – rsinha Oct 12 '16 at 19:12
  • By INT_MIN, I mean the smallest number encoded by the operand size of the dividend. – rsinha Oct 12 '16 at 19:19
  • 1
    `Is it possible to have CPU not even generate the FP exceptions`: yes, that's the default situation, where all the mask bits in the x87 control word and MXCSR are set by default. – Peter Cordes Oct 12 '16 at 19:25
  • 1
    re: integer division: no, DIV and IDIV do 128b / 64b => 64b division. If RDX isn't zero (DIV) or set with CQO from RAX (IDIV), then divide errors can easily happen. But if you are just using it for 64b / 64b => 64b division like compilers normally do, then yes, `x/0` for DIV and IDIV, and `INT_MIN / -1` for IDIV only are the only exception cases: http://stackoverflow.com/questions/39982609/minimum-values-to-cause-idiv-instruction-to-overflow-in-x86-assembly – Peter Cordes Oct 12 '16 at 19:29
  • Thank you Peter! That makes sense. You have been super helpful. – rsinha Oct 12 '16 at 19:33

1 Answers1

2

Is it possible to have CPU not even generate the FP exceptions

Yes, that's the default situation for most OSes, where all the mask bits in the x87 control word and MXCSR are set. If you're not sure for some custom OS, it's easy to set them all at the top of main() or something.

would it suffice to check two cases: 1) divisor is not 0, and 2) divisor and dividend are not -1 and INT_MIN, respectively?

No. no, DIV and IDIV do 128b / 64b => 64b division (or 64/32=>32). If RDX isn't zero (DIV) or set with CQO from RAX (IDIV), then divide errors can easily happen.

But if you are just using it for 64b / 64b => 64b division like compilers normally do, then yes, the only exception cases limited.

  • x/0 for DIV and IDIV
  • LONG_MIN / -1 for IDIV
  • dividends larger than the operand size aren't possible if you set RDX from RAX.

Minimum Values to Cause idiv Instruction to Overflow in x86 Assembly

Community
  • 1
  • 1
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847