uses DOS;
var No:Byte;P:^Byte;PP:Pointer;x,y:integer;isErr:Boolean;
Procedure NN; interrupt;
Begin
writeln('Err DBZ...');
y:=0;
isErr:=true;
End;
Begin
isErr:=false;
{PP:=PTR($0,$0);}
No:=0;
getIntVec(No,PP);
setIntVec(No,addr(NN));
Readln(x);
writeln(1 div (2-x));
setIntVec(No,PP);
readln;
End.
Обработка вектора прерывания (0).
Столкнулся с необходимостью ручной обработки ошибок вычислений
(Деление на 0, неверный параметр корня и т.д.).
Собсно как я понял в Паскале единственный способ это сделать, это перенаправить вектор прерываний?
Написал небольшой примерчик,
Код:
Но возник вопрос, как вернуть управление в программу из функции на которую ссылается правленный вектор?
Если в процедуре прописать исходный вектор setIntVec(No,PP);, то программа все - равно выпадает с Division by Zero.
Мне нужно, чтобы в случае деления на нуль, устанавливался флаг ошибки, модифицировалась переменная и продолжилась линия основной программы, как это можно реализовать? И если кто знает, какое прерывание отвечает за извлечение корня из отрицательного числа?
P.S.> Сейчас функция NN при делении на 0 (вводе 2) зацикливается и выход из нее не происходит :(
P.P.S.> Может есть более рациональный способ реализовать это ?
(проверку делителя на <>0 не предлагать :) )
Заранее огромное спасибо кто откликнется :p
возврат происходит по адресу инструкции вызвавшей прерывание . так как аргументы не изменились , то прерывание присходит снова .
Цитата: koderAlex
возврат происходит по адресу инструкции вызвавшей прерывание . так как аргументы не изменились , то прерывание присходит снова .
Это возможно обойти ?
Простое изменение переменной x не помогает =(
надо изменить или адрес возврата , или аргументы команды в обработчике прерывания .
так все равно зацикливается :(
Код:
uses DOS;
var No:Byte;P:^Integer;PP:Pointer;x,y:integer;
Procedure NN; interrupt;
Begin
writeln('Error...',x);
y:=0;
x:=x-1;
End;
Begin
No:=$0;
getIntVec(No,PP);
setIntVec(No,addr(NN));
Readln(x);
y:=(1 div (2-x));
setIntVec(No,PP);
readln;
End.
var No:Byte;P:^Integer;PP:Pointer;x,y:integer;
Procedure NN; interrupt;
Begin
writeln('Error...',x);
y:=0;
x:=x-1;
End;
Begin
No:=$0;
getIntVec(No,PP);
setIntVec(No,addr(NN));
Readln(x);
y:=(1 div (2-x));
setIntVec(No,PP);
readln;
End.
естественно . ты же меняеш значение переменной , а не значение регистра . посмотри под дебагером в какой регистр кладётся переменная и в обработчике вставь строчку вида : asm{inc [регистр]};