На современных процессорах, Celecon, Pentium II, III, при
запуске
программ, написанных на Turbo Pascal возникает ошибка Error
200
(указание адреса). Как разрешить эту проблему ?
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
25-11-2004 12:41
Вот утилита для исправления ошибки деления на ноль в EXE-модулях, скомпилированных TP/BP с использованием модуля Crt. Побочный эффект от такого патча - не будет правильно работать функция Delay из модуля Crt, а именно - реальная задержка будет на 3 порядка короче (если не указывать значение для патча, по-умолчанию 65535).
Исправлению подвергается константа размером WORD в следующем коде (исходник CRT.ASM):
MOV CX,55 DIV CX
MOV DelayCnt,AX
Это часть кода инициализации модуля CRT, где после определения частоты процессора вычисляется константа, требуемая для работы функции Delay. 55 - это период системного таймера в миллисекундах. Вследствие деления слишком большого числа в DX:AX на эту константу результат не помещается в регистре AX, что и приводит к аппаратному перерыванию INT 0 (Divide error).
Для компиляции новых программ на BP/TP без этой ошибки следует отказаться от использования Crt, либо пропатчить исходник CRT.ASM в RTL и перекомпилировать Crt. Можно также воспользоваться этой утилитой для патчинга CRT.OBJ или TURBO.TPL/TPP.TPL.
program bpzeropatch;
{$APPTYPE CONSOLE}
uses
SysUtils;
const
Sign = #$F7#$D0#$F7#$D2#$B9;
Patch : word = $FFFF;
var
F : File;
S : string;
P : integer;
begin
if ParamCount = 0 then
begin
writeln('Usage:');
writeln('filename [patch]');
exit;
end;
if ParamCount > 1 then Patch := strtoint(ParamStr(2));
Assign(F, ParamStr(1));
Reset(F, 1);
Setlength(S, FileSize(F));
BlockRead(F, S[1], length(S));
P := pos(Sign, S);
if P = 0 then
writeln(format('%s : File is packed, or no error exist.', [ParamStr(1)]))
else
begin
inc(P, length(Sign));
Seek(F, P-1);
BlockWrite(F, Patch, sizeof(Patch));
writeln(format('%s : Successful file patched. Old value: %.2x%.2x',
[ParamStr(1), ord(s[p+1]), ord(s[p])]));
end;
Close(F);
end.
Ошибку дает модуль CRT. Уберите этот модуль из программы,
если необходимо, перепишите все CRT-ные функции в ручную
и пользуйтесь приложением наздоровье. Так-же можно попробовать
с помощью отладчика найти место ошибки, и исправить в исходном
модуле CRT. Насколько я помню, это ошибка - деление не 0.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.