|
ERROR 200 | Описание | Информация | Маленькая резидентная программа (размер кода - 38 байтов, резидент - 14 байтов) - для борьбы с "runtime error 200" без перекомпиляции или применения патчей.
Подлинно крутая программа. Высший пилотаж, непобоюсь. Однозначно - маст хэв.
Пояснение алгоритма её работы:
- При запуске эта утилита перехватывает <int 21h/2500h> (DOS SET VECTOR 0) и в дальнейшем запрещает таким образом перехват <int0> другими программами, если они используют для этого <int 21h/2500h> (DOS SET VECTOR 0). А глючная паскалевская библиотека CRT в TP7 именно этой функцией и пользуется. Следовательно, программа, в которой эта "Ошибка 200", при запуске не перехватит прерывание <int 0> (divide by zero error). Зато его перехватывает при запуске эта резидентная утиль. По приходе прерывания "divide by zerro" (int 0) эта программа увеличивает на единичку значение CX, (в котором при ошибке было изначально 37h ), и делает <iret> на адрес инструкции, которая вызвала прерывание <int 0> - это инструкция <div cx> в паскалевской библиотеке CRT. Если это увеличенное на 1 значение делителя в CX снова вызовет переполнение результата (int 0), то делитель (CX) в обработчике этой резидентной утилиты снова увеличивается на 1 и снова выполняется <iret> на инструкцию <div cx>, которая вызвала это прерывание.Так и будет это прерывание генерироваться на инструкции <div cx> в коде CRT, пока деление не пройдёт без ошибки, и тогда выполнение инициализации TP CRT пойдёт дальше уже без ошибок. - Очень элегантное решение проблемы "Error 200" в программах на TP7. .
| Раздел: Turbo Pascal Pentium II DIV BUG fixing Скриншоты Операционная система: DOS Требования: - Автор: - Издатель: -
Добавил: OldCompUser (2016.10.02) | Доступные файлы - сортировка по имени и версии, времени добавления Файлов: 2. Файл | Размер | Выпуск | Версия | Язык | Качество | Загрузил | | 0.2 Кб | | | | ![[Не подделка]](http://old-dos.ru/img/nofake.png) | OldCompUser 2016.10.02 | | 0.9 Кб | 2016 | (fixed) | | ![[Не подделка]](http://old-dos.ru/img/nofake.png) | Nika 2016.10.04 | Пришлось добавить 2 байта кода, чтобы не выделялась лишняя память для резидента. Старый вариант тоже включён в этот архив. Итого - 40 байтов, резидент 15 байтов. |
 |
Комментарии | #1 Автор: SokilOff (2016.10.04 21:24) | >Очень элегантное решение проблемы "Error 200"
А если переполнение пройзойдёт в другой программе, использующей int 21h/2500h ? На выходе получим непредсказуемое поведение ? |
#2 Автор: Nika (2016.10.04 23:31, изменений: 2, 2016.10.07 01:12) | Программы перехватывают <int0> практически всегда только для того, чтобы в случае ошибки при делении сообщить "ERROR - division by zero" и завершиться. При работе рассматриваемой резидентной программы те другие программы в случае ошибок деления да, будут вести себя странно.
Поэтому в рассматриваемую резидентную программу, по-хорошему, надо было бы включить сигнатурную проверку участка кода, вызвавшего <int0>, и выполнение инкремента делителя выполнять только для фрагментов кода инициализации CRT.TPU TP7. А для остальных программ передавать управление в их обработчик <int0>. Но тогда нужно отслеживать состояние собственного обработчика <int0>, чтобы он был первым в цепочке обработчиков. Это бы сильно усложнило программу, а она специально сделана в минималистичном стиле.
Решение, как в этой программе,безусловно, не является 100% корректным, хотя и имеет право на существование в принципе. Вот что следовало бы сделать для улучшения этого алгоритма - это добавить возможность выгрузки резидента при повторном запуске. Тогда для запуска программы на TP7 с "ошибкой 200" можно было бы написать BAT-файл - для запуска резидента, запуска проблемной программы и по её завершении повторного запуска резидента для выгрузки ранее запущенного.
Примерно так.
|
| |
|