Integer Divide Exception

Hi.

I'm writing some assembly code which should run under windows. for speed I converted one of my float routines to integer (I want to use mmx).

The problem is, that my integer code sometimes (every 5 minutes or so) generates a divide by zero or divide overflow exception.

Under dos I usually solved the problem with a simple interrrupt-handler which just returns to the caller.


Now I want to do exactly this under windows. How do I catch this exception and continue my code?

I'm using c for the OS stuff btw..

Nils

LVL 4
nils pipenbrinckAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
The best thing to handle this kind of situation would be using SEH aka 'Structured Exception Handling' - it mainly works like this:

__try
{
 // malicious code
}
__except ( EXCEPTION_INT_DIVIDE_BY_ZERO = GetExceptionCode()) // make sure to only handle exceptions we want
{
 // exception handling code here
}

Feel free to ask if you need more information!
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jkrCommented:
Or you could alternatively install a top-level SEH exception handler by calling 'SetUnhandledExceptionFilter()' to replace the global 'UnhandledExceptionFilter()' (which will usually signal the exception to the user with one of these 'nice' message boxes and terminate the program) with your own, e.g.

LONG WINAPI __XceptFilter   (   EXCEPTION_POINTERS* pExp)
{
    LONG    lnRC    =   EXCEPTION_EXECUTE_HANDLER;
#ifdef _DEBUG
    char    acXcept[ 1024];

    sprintf (   acXcept,
                "__XceptFilter(): got exception, code == 0x%x @ 0x%x, flags == 0x%x",  
                            pExp->ExceptionRecord->ExceptionCode,
                ( DWORD)    pExp->ExceptionRecord->ExceptionAddress,
                            pExp->ExceptionRecord->ExceptionFlags
            );
#endif

    if  (   EXCEPTION_INT_DIVIDE_BY_ZERO    ==  pExp->ExceptionRecord->ExceptionCode)
        {
            return( EXCEPTION_CONTINUE_EXECUTION);
        }

    return( lnRC);
}

// ...

      SetUnhandledExceptionFilter      (      __XceptFilter);
0
nils pipenbrinckAuthor Commented:
hi ikr..

your code works on a small testfile I wrote.. the problem is, that if I have initialized directx and switched to fullscreen graphics the __try stuff is the fastest way to reboot my computer :)

I guess it's not your fault, but I leave this question open some more hours...


Since I don't want to use my clib (the __try implementation differs from compiler to compiler) I tried it using an unhandled exception filter..

The problem is, that this code causes a stack  overflow.. (no matter how many stack i have..) Any ideas?


#include <windows.h>

LONG gpffilter(EXCEPTION_POINTERS *pExp)
{
  if (EXCEPTION_INT_DIVIDE_BY_ZERO  ==  pExp->ExceptionRecord->ExceptionCode)
    return(EXCEPTION_CONTINUE_EXECUTION);

  return(EXCEPTION_EXECUTE_HANDLER);
}


void main (void)
{

  SetUnhandledExceptionFilter(gpffilter);

  ; make a div/zero error...
  _asm {
    pushad
    mov  eax, 0
    mov  edx, 1
    mov  ecx, 0
    idiv ecx
    popad
  }

  MessageBox (0,"cool, it workes","debug", 0);
}



0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

jkrCommented:
Hmm, I'm not too good at assembler ;-)

Have you tried sth. simple like that

int a,b,c;

a = 1;
b = 0;

c = a / b;

?
0
nils pipenbrinckAuthor Commented:
no.. I haven't tried it..

my compiler (watcom) won't compile this code because it's obviously buggy (it does nothing but a divide by zero).

that code I used does nothing but a 64bit / 32bit divide where the 64 bit value is 0x100000000 and the 32 bit value is 0. (just for your information).

I think your answer is correct, even if it doesn't work for me.

I now check the values before I divide. This works around my problem (and is cleaner than the div/zero hack).

Nils

0
jkrCommented:
Thanx!

Well, Watcom is a bit picky sometimes, isn't it <g>?

BTW: Your name sounds qiute German - am I right?
0
nils pipenbrinckAuthor Commented:
yep.. it doesn't only sound german.. it actually _is_ german. hallo :)

watcom might be picky, but it lets me do what I want (even strangest things like writing programs without linking any clib objects and stuff like that).

I simply love the compiler.. I've never seen anything flexible as watcom c. (to bad there will most likely never be a release 12 with p6 codegen).

Nils


0
jkrCommented:
Kann ich nur zustimmen - der Optimizer is' mit vom Feinsten. Wir haben hier auch noch einen in der Version 10.0 rumstehen, aber leider is' ja mittlerweile VC++ ein Muß :-(

Gruß aus dem Schwabenland ;-)

Jürgen
0
nils pipenbrinckAuthor Commented:
Gruß aus Hamburg :)

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.