Board index » delphi » Division by Zero!

Division by Zero!

I have a problem with Division by Zero!

My code is below, its just a simple adding program - can anyone get this to
run please?

After run it loops writing only 'You just divided by zero!'

Thanks in advance
Tasos

-----

Program DivisionByZero;

uses Dos;

var SaveInt00 : pointer;
      zero : byte;

procedure ZeroDivided; interrupt;
begin
    writeln('You just divided by zero!');
end;

begin
    zero := 0;
    GetIntVec(0, SaveInt00);
    SetIntVec(0, @ZeroDivided);
    writeln( 100 / 4);
    writeln(172 / zero);
    writeln(1024 / 3);
    SetIntVec(0, SaveInt00);
end.

 

Re:Division by Zero!


Hi!

Quote
> My code is below, its just a simple adding program - can anyone get this
to
> run please?

Trying...

Quote
> After run it loops writing only 'You just divided by zero!'

> Thanks in advance
> Tasos

> -----
> Program DivisionByZero;

> uses Dos;

> var SaveInt00 : pointer;
>       zero : byte;

> procedure ZeroDivided; interrupt;
> begin
>     writeln('You just divided by zero!');
> end;

DIV0 interrupt is a recoverable error, so after your interrupt finishes, it
jumps to the instruction which divided by 0. So the error will occur once
again etc.
I'm not sure if it'll work directly, but since your divisor is stored in AX
( or similar ) you need to change it to a value <> 0:

procedure ZeroDivided; interrupt;
begin
    writeln('You just divided by zero!');

    asm
        mov al, 1
    End;
end;

This should work if the compiler doesn't save all registers - IMHO none does
this.

Quote
> begin
>     zero := 0;
>     GetIntVec(0, SaveInt00);
>     SetIntVec(0, @ZeroDivided);
>     writeln( 100 / 4);
>     writeln(172 / zero);
>     writeln(1024 / 3);
>     SetIntVec(0, SaveInt00);
> end.

If you want to learn more about those processor generated interrupts, take a
look at the intel specifications. Sorry can't remember a link, but you'll
find it under developer section - INTEL.com

-
Dennis

Re:Division by Zero!


Hallo Anastasios!

Thursday 12 April 2001 19:09, Anastasios Balaouras wrote to All:

 AB> I have a problem with Division by Zero!

 AB> My code is below, its just a simple adding program - can anyone get
 AB> this to run please?

 AB> After run it loops writing only 'You just divided by zero!'

 AB> Thanks in advance
 AB> Tasos

 AB> -----

 AB> Program DivisionByZero;

 AB> uses Dos;

 AB> var SaveInt00 : pointer;
 AB>       zero : byte;

 AB> procedure ZeroDivided; interrupt;
 AB> begin
 AB>     writeln('You just divided by zero!');
 AB> end;

 AB> begin
 AB>     zero := 0;
 AB>     GetIntVec(0, SaveInt00);
 AB>     SetIntVec(0, @ZeroDivided);
 AB>     writeln( 100 / 4);
 AB>     writeln(172 / zero);
 AB>     writeln(1024 / 3);
 AB>     SetIntVec(0, SaveInt00);
 AB> end.

You are trapped in your exit-procedure. But I am not so familiar with such
problems.

Perheaps you can extract some helpful information from the unit included below,
it contains routines to patch the return address of error-exit procedures:

=== Cut ===
{***********************************************************}
{*                                                         *}
{*               ERROR.PAS                                 *}
{*                                                         *}
{*  Abfangen von Laufzeitfehlern unter Turbo-Pascal 4.0    *}
{*  (c) 1988 Karsten Gieselmann & Pascal International     *}
{*                                                         *}
{*  !!! Diese Unit muss als letzte der UNITs in der        *}
{*  USES- Anweisung angefuehrt werden, welche selbst       *}
{*  eine Exit-Routine installieren                         *}
{*                                                         *}
{*   Pascal 5'88 Seite 59                                  *}
{*                                                         *}
{*   GG/88                                                 *}
{***********************************************************}

Unit Error;

Interface

Var
   Continueaftererror : Boolean;
   { soll das Programm nach Fehlerbehandlung weiterlaufen ? }

   Errorstohandle : Set Of Byte;
   { die Codes der abzufangenden Fehler ( siehe Handbuch )}

   {***********************************************************}
   {*                                                         *}
   {*  uebergibt die Fehlerbehandlung einer benutzer-         *}
   {*  definierten Routine  mit Syntax:                       *}
   {*                                                         *}
   {*  PROCEDURE XYZ (Number:BYTE;Address : POINTER )         *}
   {*                                                         *}
   {*  wobei "Number" die Fehlernummer und "Address"          *}
   {*  die Fehleradresse bedeuten.                            *}
   {*  Diese vom Benutzer eingesetzte Routine muss            *}
   {*  unbedingt im Far -Modell kompiliert werden             *}
   {*                                                         *}
   {*                                                         *}
   {***********************************************************}

    Procedure Seterrorhandler ( Userproc : Pointer );

    { uebergibt die Fehlerbehandlung der Standardroutine
    dieser Unit }

        Procedure Reseterrorhandler;

Implementation

Var
   Exitsave,                   { Zeiger auf naechste Exit-Routine }
   Errorhandler : Pointer;     { Zeiger auf Fehlerbehandlung      }
   Maincseg     : Word;        { Code-Segment des Hauptprog.      }

   { die naechsten beiden Proceduren muessen FAR kompiliert werden }
   {$F+}

    Procedure Defaulthandler ( Number : Byte; Address : Pointer );
    Begin
       Writeln;
       Writeln ('Laufzeit-Fehler Nr.: ',Number,' aufgetreten ! ');
    End;

    Procedure Errorexit;

       Procedure Callerrorhandler ( Number : Byte;Address : Pointer );
       Inline ( $Ff / $1E / Errorhandler );

       Procedure Patchreturnaddress;
       Inline ( $C4 / $16 / Erroraddr / $8C /
       $C0 / $03 / $06 / Maincseg /
       $89 / $46 / $04 / $89 / $56 / $02 );

    Begin
       If Exitcode In Errorstohandle Then
       Begin
          {Fehlerbehandlung}
          Callerrorhandler ( Exitcode,Erroraddr );
          If Continueaftererror Then
          Begin
             {Ruecksprung zur Fehleraddresse }
             Patchreturnaddress;    {Fehleraddresse}
             Exitcode := 0;         { so tun als ob kein Fehler gewesen waere }
             Erroraddr := Nil;
             Exitproc := @Errorexit;   {Exit Zeiger wieder auf diese Routine }
          End
          Else
          Exitproc := Exitsave;
       End
       Else
       Exitproc := Exitsave; { Fehler nicht abfangen, Ende }
    End;
{$F-}

    Procedure Seterrorhandler ( Userproc : Pointer );
    Begin
       Errorhandler := Userproc;
    End;

    Procedure Reseterrorhandler;
    Begin
       Errorhandler := @Defaulthandler;
    End;

{ Unit Installieren }
Begin
   Continueaftererror := True;    { Defaultwerte setzen }

   Errorstohandle := [200,205..207]; { Standardbehandlung der Unit }

   { Fehlerroutine in ExitKette einklinken }
   Exitsave := Exitproc;
   Exitproc := @Errorexit;

   {Offset des Haupt -CS ermitteln }
   Inline ( $8B / $46 / $02 / $A3 / Maincseg );
End.

(*
Program ErrorDemo;

Uses Break,Error;

Const
 Dummy : Byte = 255;

{$F+}
procedure UserHandler(Number : Byte; Address : Pointer );
Begin
Writeln;
writeln('Achtung: Fehler Nr.: ',Number,' aufgetreten ! ');
End;
{$F-}

Begin
{ SetErrorHandler(@UserHandler); }

{ nur Floating-Point Fehler abfangen }
ErrorsToHandle :=[200,205..207];
ContinueAfterError:=True;

Writeln;
{writeln(1/0);}
Writeln('Der naechste Fehler wird nicht abgefangen :');
dummy:=dummy * dummy ;
end.
*)
=== Cut ===

   Servus  Gottfried

Re:Division by Zero!


Hi Dennis,
  and Good Easter!

Thanks for your asnwer,

I tried it, but not fixed my problem.

BTW, I check the second number if  0 and display message bla bla

-
Tasos

Quote
"Dennis Waldherr" <Dennis.Waldh...@gmx.de> wrote in message news:9b5d7r$7taom$1@ID-80126.news.dfncis.de...
> Hi!

> > My code is below, its just a simple adding program - can anyone get this
> to
> > run please?
> Trying...

> > After run it loops writing only 'You just divided by zero!'

> > Thanks in advance
> > Tasos

> > -----

> > Program DivisionByZero;

> > uses Dos;

> > var SaveInt00 : pointer;
> >       zero : byte;

> > procedure ZeroDivided; interrupt;
> > begin
> >     writeln('You just divided by zero!');
> > end;
> DIV0 interrupt is a recoverable error, so after your interrupt finishes, it
> jumps to the instruction which divided by 0. So the error will occur once
> again etc.
> I'm not sure if it'll work directly, but since your divisor is stored in AX
> ( or similar ) you need to change it to a value <> 0:

> procedure ZeroDivided; interrupt;
> begin
>     writeln('You just divided by zero!');

>     asm
>         mov al, 1
>     End;
> end;

> This should work if the compiler doesn't save all registers - IMHO none does
> this.

> > begin
> >     zero := 0;
> >     GetIntVec(0, SaveInt00);
> >     SetIntVec(0, @ZeroDivided);
> >     writeln( 100 / 4);
> >     writeln(172 / zero);
> >     writeln(1024 / 3);
> >     SetIntVec(0, SaveInt00);
> > end.

> If you want to learn more about those processor generated interrupts, take a
> look at the intel specifications. Sorry can't remember a link, but you'll
> find it under developer section - INTEL.com

> -
> Dennis

Re:Division by Zero!


Hi Gottfried
  and Good Easter!

Thanks for your asnwer,

I tried it, but not fixed my problem.

BTW, I check the second number if  0 and display message bla bla

-
Tasos

Quote
"Gottfried Gidaly" <Gottfried.Gid...@mailer.fido.at> wrote in message news:MSGID_2=3A313=2F37.79=40fidonet.org_3ad698ac@fidonet.org...
> Hallo Anastasios!

> Thursday 12 April 2001 19:09, Anastasios Balaouras wrote to All:

>  AB> I have a problem with Division by Zero!

>  AB> My code is below, its just a simple adding program - can anyone get
>  AB> this to run please?

>  AB> After run it loops writing only 'You just divided by zero!'

>  AB> Thanks in advance
>  AB> Tasos

>  AB> -----

>  AB> Program DivisionByZero;

>  AB> uses Dos;

>  AB> var SaveInt00 : pointer;
>  AB>       zero : byte;

>  AB> procedure ZeroDivided; interrupt;
>  AB> begin
>  AB>     writeln('You just divided by zero!');
>  AB> end;

>  AB> begin
>  AB>     zero := 0;
>  AB>     GetIntVec(0, SaveInt00);
>  AB>     SetIntVec(0, @ZeroDivided);
>  AB>     writeln( 100 / 4);
>  AB>     writeln(172 / zero);
>  AB>     writeln(1024 / 3);
>  AB>     SetIntVec(0, SaveInt00);
>  AB> end.

> You are trapped in your exit-procedure. But I am not so familiar with such
> problems.

> Perheaps you can extract some helpful information from the unit included below,
> it contains routines to patch the return address of error-exit procedures:

> === Cut ===
> {***********************************************************}
> {*                                                         *}
> {*               ERROR.PAS                                 *}
> {*                                                         *}
> {*  Abfangen von Laufzeitfehlern unter Turbo-Pascal 4.0    *}
> {*  (c) 1988 Karsten Gieselmann & Pascal International     *}
> {*                                                         *}
> {*  !!! Diese Unit muss als letzte der UNITs in der        *}
> {*  USES- Anweisung angefuehrt werden, welche selbst       *}
> {*  eine Exit-Routine installieren                         *}
> {*                                                         *}
> {*   Pascal 5'88 Seite 59                                  *}
> {*                                                         *}
> {*   GG/88                                                 *}
> {***********************************************************}

> Unit Error;

> Interface

> Var
>    Continueaftererror : Boolean;
>    { soll das Programm nach Fehlerbehandlung weiterlaufen ? }

>    Errorstohandle : Set Of Byte;
>    { die Codes der abzufangenden Fehler ( siehe Handbuch )}

>    {***********************************************************}
>    {*                                                         *}
>    {*  uebergibt die Fehlerbehandlung einer benutzer-         *}
>    {*  definierten Routine  mit Syntax:                       *}
>    {*                                                         *}
>    {*  PROCEDURE XYZ (Number:BYTE;Address : POINTER )         *}
>    {*                                                         *}
>    {*  wobei "Number" die Fehlernummer und "Address"          *}
>    {*  die Fehleradresse bedeuten.                            *}
>    {*  Diese vom Benutzer eingesetzte Routine muss            *}
>    {*  unbedingt im Far -Modell kompiliert werden             *}
>    {*                                                         *}
>    {*                                                         *}
>    {***********************************************************}

>     Procedure Seterrorhandler ( Userproc : Pointer );

>     { uebergibt die Fehlerbehandlung der Standardroutine
>     dieser Unit }

>         Procedure Reseterrorhandler;

> Implementation

> Var
>    Exitsave,                   { Zeiger auf naechste Exit-Routine }
>    Errorhandler : Pointer;     { Zeiger auf Fehlerbehandlung      }
>    Maincseg     : Word;        { Code-Segment des Hauptprog.      }

>    { die naechsten beiden Proceduren muessen FAR kompiliert werden }
>    {$F+}

>     Procedure Defaulthandler ( Number : Byte; Address : Pointer );
>     Begin
>        Writeln;
>        Writeln ('Laufzeit-Fehler Nr.: ',Number,' aufgetreten ! ');
>     End;

>     Procedure Errorexit;

>        Procedure Callerrorhandler ( Number : Byte;Address : Pointer );
>        Inline ( $Ff / $1E / Errorhandler );

>        Procedure Patchreturnaddress;
>        Inline ( $C4 / $16 / Erroraddr / $8C /
>        $C0 / $03 / $06 / Maincseg /
>        $89 / $46 / $04 / $89 / $56 / $02 );

>     Begin
>        If Exitcode In Errorstohandle Then
>        Begin
>           {Fehlerbehandlung}
>           Callerrorhandler ( Exitcode,Erroraddr );
>           If Continueaftererror Then
>           Begin
>              {Ruecksprung zur Fehleraddresse }
>              Patchreturnaddress;    {Fehleraddresse}
>              Exitcode := 0;         { so tun als ob kein Fehler gewesen waere }
>              Erroraddr := Nil;
>              Exitproc := @Errorexit;   {Exit Zeiger wieder auf diese Routine }
>           End
>           Else
>           Exitproc := Exitsave;
>        End
>        Else
>        Exitproc := Exitsave; { Fehler nicht abfangen, Ende }
>     End;
> {$F-}

>     Procedure Seterrorhandler ( Userproc : Pointer );
>     Begin
>        Errorhandler := Userproc;
>     End;

>     Procedure Reseterrorhandler;
>     Begin
>        Errorhandler := @Defaulthandler;
>     End;

> { Unit Installieren }
> Begin
>    Continueaftererror := True;    { Defaultwerte setzen }

>    Errorstohandle := [200,205..207]; { Standardbehandlung der Unit }

>    { Fehlerroutine in ExitKette einklinken }
>    Exitsave := Exitproc;
>    Exitproc := @Errorexit;

>    {Offset des Haupt -CS ermitteln }
>    Inline ( $8B / $46 / $02 / $A3 / Maincseg );
> End.

> (*
> Program ErrorDemo;

> Uses Break,Error;

> Const
>  Dummy : Byte = 255;

> {$F+}
> procedure UserHandler(Number : Byte; Address : Pointer );
> Begin
> Writeln;
> writeln('Achtung: Fehler Nr.: ',Number,' aufgetreten ! ');
> End;
> {$F-}

> Begin
> { SetErrorHandler(@UserHandler); }

> { nur Floating-Point Fehler abfangen }
> ErrorsToHandle :=[200,205..207];
> ContinueAfterError:=True;

> Writeln;
> {writeln(1/0);}
> Writeln('Der naechste Fehler wird nicht abgefangen :');
> dummy:=dummy * dummy ;
> end.
> *)
> === Cut ===

>    Servus  Gottfried

Re:Division by Zero!


Anastasios Balaouras schreef:
Quote

> Hi Gottfried
>   and Good Easter!

> Thanks for your asnwer,

> I tried it, but not fixed my problem.

> BTW, I check the second number if  0 and display message bla bla

> -
> Tasos

> "Gottfried Gidaly" <Gottfried.Gid...@mailer.fido.at> wrote in message news:MSGID_2=3A313=2F37.79=40fidonet.org_3ad698ac@fidonet.org...
> > Hallo Anastasios!

> > Thursday 12 April 2001 19:09, Anastasios Balaouras wrote to All:

> >  AB> I have a problem with Division by Zero!

<snip>

Why do you use Int00 in you're program?
IIRC it has everything to do with timers and _nothing_
with division by zero. You must use either a
Critical Error Interrupt Vector (Int23?) or hook in
to TP's own ErrorHandler-chain like Gottfried has showed you.

BTW: var SaveInt00 is defined in the system-unit of TP to
take over the previous Int00. So it's already for internal use
of TP. (See SYSTEM.DOC; interface section of SYSTEM.TPU)

Greetings. Huub.

Re:Division by Zero!


Huub van Dooren <hvdoo...@iae.nl> wrote:

Quote
> Anastasios Balaouras schreef:

> > Hi Gottfried
> >   and Good Easter!

> > Thanks for your asnwer,

> > I tried it, but not fixed my problem.

> > BTW, I check the second number if  0 and display message bla bla

> > -
> > Tasos

> > "Gottfried Gidaly" <Gottfried.Gid...@mailer.fido.at> wrote in message news:MSGID_2=3A313=2F37.79=40fidonet.org_3ad698ac@fidonet.org...
> > > Hallo Anastasios!

> > > Thursday 12 April 2001 19:09, Anastasios Balaouras wrote to All:

> > >  AB> I have a problem with Division by Zero!

> <snip>

> Why do you use Int00 in you're program?
> IIRC it has everything to do with timers and _nothing_
> with division by zero. You must use either a
> Critical Error Interrupt Vector (Int23?) or hook in
> to TP's own ErrorHandler-chain like Gottfried has showed you.

No. Timer is IRQ 0 respective Int 08. Int 0 is the 8086 exception
handler for divby0.

Quote
> BTW: var SaveInt00 is defined in the system-unit of TP to
> take over the previous Int00. So it's already for internal use
> of TP. (See SYSTEM.DOC; interface section of SYSTEM.TPU)

Yes, to display the RTE200 message.

--
#!/usr/bin/perl
eval($0=q{$0="\neval(\$0=q{$0});\n";for(<*.pl>){open X,">>$_";print X
$0;close X;}print''.reverse"\nsuriv lreP trohs rehtona tsuJ>RH<\n"});
####################### http://learn.to/quote #######################

Re:Division by Zero!


"echo 'Rudolf Polzer'>/dev/null" schreef:

Quote

> Huub van Dooren <hvdoo...@iae.nl> wrote:
> > Anastasios Balaouras schreef:

> > > Hi Gottfried
> > >   and Good Easter!

> > > Thanks for your asnwer,

> > > I tried it, but not fixed my problem.

> > > BTW, I check the second number if  0 and display message bla bla

> > > -
> > > Tasos

> > > "Gottfried Gidaly" <Gottfried.Gid...@mailer.fido.at> wrote in message news:MSGID_2=3A313=2F37.79=40fidonet.org_3ad698ac@fidonet.org...
> > > > Hallo Anastasios!

> > > > Thursday 12 April 2001 19:09, Anastasios Balaouras wrote to All:

> > > >  AB> I have a problem with Division by Zero!

> > <snip>

> > Why do you use Int00 in you're program?
> > IIRC it has everything to do with timers and _nothing_
> > with division by zero. You must use either a
> > Critical Error Interrupt Vector (Int23?) or hook in
> > to TP's own ErrorHandler-chain like Gottfried has showed you.

> No. Timer is IRQ 0 respective Int 08. Int 0 is the 8086 exception
> handler for divby0.

> > BTW: var SaveInt00 is defined in the system-unit of TP to
> > take over the previous Int00. So it's already for internal use
> > of TP. (See SYSTEM.DOC; interface section of SYSTEM.TPU)

> Yes, to display the RTE200 message.

> --
> #!/usr/bin/perl
> eval($0=q{$0="\neval(\$0=q{$0});\n";for(<*.pl>){open X,">>$_";print X
> $0;close X;}print''.reverse"\nsuriv lreP trohs rehtona tsuJ>RH<\n"});
> ####################### http://learn.to/quote #######################

Thanks for the update.
I now know why the RTE200 is displayed.

Greetings. Huub

Other Threads