Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Деление на ноль

60K
25 марта 2011 года
alexeivyg
15 / / 26.11.2010
Есть задача: имеется 2 INTовских числа x и y. Необходимо поделить x на y, причём y=0. Программа должна поделить на 0, а лишь потом проверить: был ли делителем 0. Программа должна адекватно себя повести при делении на 0 и не закрыться со страху.
Думал,что нужно использовать прерывание INT 00h, но не понимаю как писать обработчик и перехватчик данного прерывания. Может кто-нибудь знает решение данной задачи без прерываний или предложит обработчик интовского прерывания?
1.8K
26 марта 2011 года
LM(AL/M)
332 / / 20.12.2005
условие "Программа должна поделить на 0, а лишь потом проверить: был ли делителем 0" автомтически означает что нужно использовать прерывание. Чтобы задать обработчик используй дос-функцию №25h.
60K
26 марта 2011 года
alexeivyg
15 / / 26.11.2010
не совсем дорубил, потому что я собирася использовать прерывание INT 00h. Объясните принцип работы данного прерывания.
1.8K
26 марта 2011 года
LM(AL/M)
332 / / 20.12.2005
вот небольшой примерчик на паскале, демонстрирующий все. Этого должно быть достаточно чтобы дорубить.
Небольшой hint: при возникновении INT 00h на стеке в качестве адреса возврата лежит адрес инструкции вызвавшей деление на 0, так что если не принять специальных мер то при выходе из обработчика все повторится -- см. операцию mov cx, 5555h в примере
Код:
(* Division by 0 handling demo (INT00) *)

uses dos;


procedure msg; near;
begin
      writeln('WARNING: division by 0!');
end;


procedure handler; assembler;
asm

          pusha
          call msg
          popa
          mov cx, 5555h   { ← fix divisor («k := k div j;» below
                            translates into instruction IDIV CX) }

          iret

end;


var k, j: byte;

Begin
      SetIntVec(0, @handler);
      asm jmp @1; db 6,6,6; @1: end;
      k := k div j;
      writeln('ok');
      readln;
End.
60K
26 марта 2011 года
alexeivyg
15 / / 26.11.2010
спасибо большое, только компилятор Free Pascal выдаёт 12 ошибок. Не могли бы Вы скинуть откомпилированный проект?
Заранее благодарен.
1.8K
27 марта 2011 года
LM(AL/M)
332 / / 20.12.2005
вобще-то чтобы работать с прерываниями надо под ДОС компилировать, я использую turbo pascal.
А что вам даст исполняемый файл? Просто сейчас довольно хлопотно компилировать т.к. я свой исходник у себя удалил а при копировании с форума в текст вставляются номера строк...
60K
27 марта 2011 года
alexeivyg
15 / / 26.11.2010
и у Вас всё в Turbo Pascal компилируется? Исполняемый файл даст мне готовую программу. У меня выдаёт ошибку "instruction are not enable" к pusha.
260
27 марта 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: alexeivyg
Исполняемый файл даст мне готовую программу.


*поднял вверх палец*

1.8K
27 марта 2011 года
LM(AL/M)
332 / / 20.12.2005
Цитата: alexeivyg
Исполняемый файл даст мне готовую программу.


а ну да... пример и вправду подходит под исходное условие...

Цитата: alexeivyg
У меня выдаёт ошибку "instruction are not enable" к pusha.


это лечится опциями компилятора -- включить генерацию инструкций 286-го. Если из командной строки то -$G+
Если из IDE то идете в Options → Compiler и там увидите что-то вроде

 
Код:
Code generation
  [ ] Force far calls        [X] Word align data
  [ ] Overlays allowed       [ ] 286 instructions
дальше думаю понятно...
60K
27 марта 2011 года
alexeivyg
15 / / 26.11.2010
спасибо)) а сама функция 5555h отвечает за переполнение регистра?
1.8K
27 марта 2011 года
LM(AL/M)
332 / / 20.12.2005
не понял вопрос. 5555h -- это просто число
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог