Этим Вы окажете большую помощь науке и медицине. См. подробнее: http://solidstate.karelia.ru/~yura/pyldin/yura/computing.htm |
1. Ошибка "200".
Стандартный модуль CRT используется во многих программах на Turbo Pascal. Но при запуске этих программ на современных компьютерах, оснащённых быстрыми процессорами, возникает ошибка "Деление на нуль" Проблема 200 получила своё название по двум причинам. Во-первых, она начинает проявляться на процессорах с тактовой частотой 200 MHz. Во-вторых, в Turbo Pascal ошибка "Деление на нуль" имеет номер 200. Разберёмся теперь в причинах возникновения этой ошибки. В модуль CRT включена процедура DELAY, которая производит задержку выполнения программы на заданное число миллисекунд. Она основана на выполнении двух вложенных циклов. Внешний цикл имеет пределы от заданного числа миллисекунд до нуля. Таким образом, легко понять, что внутренний цикл должен выполняться ровно 1 миллисекунду. Стандартная процедура DELAY: 8BDC mov bx,sp Внутренний цикл: <3> 2D0100 sub ax,0001 В модуле CRT есть инициализационная часть, в которой производятся все необходимые подготовки, в том числе и расчёт, сколько же раз должен выполниться внутренний цикл, чтобы отсчитать 1 миллисекунду. Часть из инициализационной секции: 8E06???? mov es,Seg0040 Для этого производятся следующие действия: Вспомним теперь, как работает ассемблеровская инструкция DIV. Она делит DX:AX на указанный аргумент (в нашем случае CX, который равен 55) и результат заносится в AX (в DX - остаток, но он нас сейчас не интересует). На процессорах, частота которых 200 MHz и выше, DX:AX, делённое на 55 оказывается больше 65535 и, поэтому, результат не может поместиться в AX. Происходит так называемое переполнение при делении. В случае переполнения (или в случае деления на нуль) автоматически вызывается прерывание INT 00. В Turbo Pascal (в модуле System) это прерывание "перехвачено". Новая процедура обслуживания INT 00 выводит строку Runtime error 200 at xxxx:xxxx. и завершает работу программы. И, несмотря на то, что к ошибке №200 мы привыкли как к делению на нуль, в этом случае имеет место не деление на нуль, а переполнение при делении. Выход из этой ситуации. В Internet'е можно найти много публикаций, где предложены различные варианты решения данной проблемы. Один из вариантов такой. В состав Borland Pascal 7.0 входит исходный текст модуля CRT, в него следует внести некоторые изменения, описанные ниже и перекомпилировать заново. Перед внесением изменений следует сделать резервную копию CRT.ASM. Рассмотрим далее, какие же изменения внесены в файл CRT.ASM: 1) Определение переменной DelayCnt (строка 45). Убрана строка: Вставлена строка: 2) Инициализационная секция. Убраны строки 105-107: Вместо них вставлены следующие: 3) Процедура Delay. Убраны строки: Вместо них вставлены следующие: Вы можете поместить новый CRT.TPU в TURBO.TPL с помощью утилиты TPUMOVER. Но прежде чем выполнять замену, следует на всякий случай сохранить старую версию TURBO.TPL. tpumover turbo.tpl -crt (Новый модуль CRT.TPU при этом должен быть в текущем каталоге). В архиве так же находится исправленный модуль CRT.TPP для программ, работающих в защищённом режиме. Вы можете проделать аналогичные действия для замены старого модуля в библиотеке TPP.TPL. При этом в текущем каталоге, в котором производится замена, не следует одновременно иметь и CRT.TPU, и CRT.TPP. Дело в том, что в программе TPUMOVER есть ошибка, в результате которой в TPP.TPL в этом случае будет помещён CRT.TPU вместо CRT.TPP. |
Если есть уже готовый EXE файл, но нет исходного текста.
В случае, если есть уже готовый EXE-файл, вызывающий ошибку 200 при запуске, но нет исходного текста программы на Паскале, следует воспользоваться следующим советом. С помощью двоичного редактора, например, HIEW, следует найти в коде последовательность байт с шестнадцатеричными кодами:
F7 D0 F7 D2 B9 37 00 F7 F1
и заменить её на последовательность:
B8 01 00 90 90 90 90 90 90
Данная замена в инициализационной секции CRT приводит к тому, что исчезает ошибка 200, но также после этого процедура Delay перестаёт давать задержку. Чтобы процедура Delay снова заработала, следует далее найти в EXE-файле последовательность байт:
33 FF 26 8A 1D A1 ?? ?? 33 D2 E8 05 00 E2 F6
и заменить её на:
B8 E8 03 F7 E1 8B CA 8B D0 B4 86 CD 15 90 90
В ассемблеровском виде новая процедура Delay представляет собой следующее:
mov ax,03E8h
mul cx
mov cx,dx
mov dx,ax
mov ah,086h
int 15h
Новая процедура Delay действительно работает и даёт нормальную задержку, однако не на всех компьютерах и операционных системах. Функция int 15h, используемая в данном варианте Delay не будет работать на старых компьютерах XT, PC, PCjr, а также под Windows NT/2000/XP/Server2003. (Под Windows NT/2000/XP/Server2003 программа работать будет нормально, но процедура Delay не будет давать задержки). Вставить полноценную новую процедуру Delay, не имея исходных текстов невозможно, так как её код длиннее, чем код старой.
2. Моя упрощенная версия модуля CRT.
Дело в том, что, как уже говорилось, модуль CRT подключает к программе инициализационную секцию, которая увеличивает размер EXE-файла на 1,5 Kb. (На самом деле эти 1,5 Kb содержат не только инициализационные процедуры, а все процедуры и функции модуля CRT, так как он написан на ассемблере цельным файлом). В инициализационной секции находятся новые драйверы текстовых устройств. Драйвер, обслуживающий стандартный файл Input, расширяет возможности Read/ReadLn, а драйвер, обслуживающий файл Output, производит вывод в видеопамять (что ускоряет работу) и позволяет использовать цвета (TextColor, TextBackground, ...). Но существует очень много программ, которые никак не используют эти возможности модуля CRT. Очень часто пользователи подключают модуль CRT к своим программам для использования процедур KeyPressed, ReadKey, GotoXY, ClrScr и т.д. Для таких процедур инициализационная секция не нужна. В этом случае она, автоматически подключившись к программе, работает впустую, только увеличивая размер EXE-файла на 1,5 Kb. |
размер | 1.0 | 3.02 | 0.98 | ||
Для использования модуля NEW_CRT необходимо в Вашей программе (и/или всех модулях, которые она использует) заменить в строчке 'uses' CRT на NEW_CRT. В случае, если программа ссылается на переменные типа CheckBreak, CheckSnow или DirectVideo, можно просто убрать эти ссылки. Как уже говорилось, в модуле NEW_CRT вывод всегда идёт через BIOS, поэтому DirectVideo подразумевается равным false, а CheckSnow, следовательно, true. |
В этом архиве находятся файлы:
DOC_CRT.TXT - Список изменений, которые следует внести в CRT.ASM
CRT.TPU - Исправленный модуль для реального режима
CRT.TPP - Исправленный модуль для защищённого режима
NEW_CRT.PAS - Альтернативный модуль CRT
Эта WEB-страничка последний раз изменялась 29 октября 2003 года.
Добавить запись в гостевую книгу | Просмотреть гостевую книгу |
< < < На главную страничку < < <