Рекомендации по улучшению работоспособности файлов, содержащих модуль CRT из Паскаля версии 7 фирмы Borland. v 3.0 beta Copyright (c) 22.09-21.10.1999 by Фёдор Меньшиков Автор рекомендации не несёт ответственности за любой вред, нанесённый вследствие применения описанных здесь действий. Признак проблемы: На быстрых компьютерах (Pentium II и старше) программа сразу кончается с надписью Runtime error 200 at XXXX:YYYY (XXXX, YYYY - четырёхзначные шестнадцатеричные числа) Компиляторы, создающие такой код: Borland (с входящим в его состав Turbo) Pascal 7.00-7.01 Самостоятельная версия Turbo Pascal 7.00 (без BP) не имеет такой ошибки. Введение. Ниже приводятся способы борьбы с данной проблемой. Каждый обладает своими достоинствами и недостатками. Какой из них применить - решать Вам. Гарантия: В исправленном файле не будет возникать ошибок, связанных с CRT, и относящихся к реализации Delay в нём, ведущих к прерыванию программы. Для разрабатывающихся программ - выполнить рекомендации для следующих файлов: CRT для TP/real mode BP находится в turbo.tpl CRT для protected mode BP находится в tpp.tpl Проблемы, возникающие при использовании данных методов: 1. Если одинаковых цепочек несколько, скорее всего, нужно выбрать первые 2. Если цепочек нет, возможно, этот файл а) компилировался не рассматриваемыми компиляторами б) сжат программами типа LZEXE в) уже неудачно исправлен Испытано на: turbo.tpl из BP 7.00 tpp.tpl из BP 7.00 файле, откомпилированном BP 7.01 в real mode. Метод 0. Достоинства: Нужно изменить всего один байт. Недостатки: Delay будет работать с расчётной задержкой в узком интервале скоростей процессора. Даже на 486 задержка меньше. На более быстрых процессорах задержка будет совсем незаметна. Вывод: Удобен для исправления exe-файлов, в которых не используется Delay. Рекомендации: Найти в файле цепочку байтов 02 f7 d0 f7 d2 заменить на (приведено новое значение байтов, которые нужно изменять) __ __ __ 33 __ Метод 1. Достоинства: Погрешность задержки при использовании Delay может достигать 50% (программа будет работать в два раза быстрей, чем предполагалось) на младших моделях Pentium II. На старших моделях погрешность практически не ощущается. На более быстрых процессорах она будет совсем незаметна. Недостатки: 1. Данный метод позволяет исправленным программам правильно работать на быстрых компьютерах, но искажает задержки при использовании процедуры Delay на медленных компьютерах (увеличивает задержку: чем медленнее процессор, тем больше задержка). 2. В будущем на компьютерах, которые будут быстрее Pentium II (233-450MHz) в 300 раз, исправленный Delay будет работать некорректно: задержка будет меньше расчётной. Вообще говоря, до 2015 года можно спать спокойно. Вывод: На компьютере, работающем на скорости от Pentium II до в 300 раз большей удобен для исправления exe-файлов, в которых использовался Delay. Рекомендации: 1. Найти в файле цепочку байтов 2d 01 00 83 da 00 72 (контрольное продолжение 05 26) заменить на 33 d2 4a 75 fd 48 74 2. Найти в файле цепочку байтов (до первой цепочки) b8 e4 ff 99 e8 3c 02 f7 d0 f7 d2 (для real mode) -- -- -- -- -- 56 -- -- -- -- -- (для protected mode) заменить на (приведено новое значение байтов, которые нужно изменять) __ ff __ 90 __ __ __ __ __ 33 __ Метод 2. Достоинства: Файлы, исправленные по этой методике, будут работать на любом компьютере от 8088 до в миллионы и миллиарды раз быстрее Pentium II. Недостатки: На любом процессоре Delay будет давать погрешность до 50%. Вывод: Ввиду независимости от скорости процессора удобен для разработки собственных программ (исправления tpl файлов). Рекомендации: 1. Найти в файле цепочку байтов 2d 01 00 83 da 00 72 05 26 3a 1d 74 f3 заменить на 90 90 90 48 74 06 e8 f7 ff e8 f7 ff 40 2. Найти в файле цепочку байтов (до первой цепочки) b8 e4 ff 99 e8 3c 02 f7 d0 f7 d2 b9 37 00 f7 f1(real mode) -- -- -- -- -- 56 -- -- -- -- -- -- -- -- -- --(protected mode) заменить на e8 40 02 40 26 3a 1d 74 f7 2d 06 00 90 90 90 90(real mode) -- 5a -- -- -- -- -- -- -- -- -- -- -- -- -- --(protected mode) ОБЪЯСНЕНИЕ (на примере real mode) (все числа шестнадцатеричные) ******************************> Исходный вариант <***************************** //Подпрограмма считает число циклов до тика 02C6 2D0100 sub ax,0001 02C9 83DA00 sbb dx,0000 02CC 7205 jb 02D3 02CE 263A1D cmp bl,es:[di] 02D1 74F3 je 02C6 02D3 C3 ret //Фрагмент, вызывающий ^ для инициализации 0080 268A1D mov bl,es:[di] 0083 B8E4FF mov ax,FFE4 0086 99 cwd 0087 E83C02 call 02C6 008A F7D0 not ax 008C F7D2 not dx 008E B93700 mov cx,0037 0091 F7F1 div cx //Вот здесь-то и было деление на ноль ******************************************************************************* **********************************> Метод 1. <********************************* // 02C6 33D2 xor dx,dx //В принципе, можно и "mov dx,ss" 02C8 4A dec dx 02C9 75FD jne 02C8 02CB 48 dec ax 02CC 7405 je 02D3 02CE 263A1D cmp bl,es:[di] 02D1 74F3 je 02C6 02D3 C3 ret // 0080 268A1D mov bl,es:[di] 0083 B8FFFF mov ax,FFFF //Цикл большой, остальное учитывать не надо 0086 90 nop 0087 E83C02 call 02C6 008A F7D0 not ax 008C 33D2 xor dx,dx 008E B93700 mov cx,0037 0091 F7F1 div cx ******************************************************************************* **********************************> Метод 2. <********************************* // 02C6 90 nop 02C7 90 nop 02C8 90 nop 02C9 48 dec ax 02CA 7406 je 02D2 02CC E8F7FF call 02C6 02CF E8F4FF call 02C6 02D2 40 inc ax 02D3 C3 ret // 0080 268A1D mov bl,es:[di] 0083 E84002 call 02C6 0086 40 inc ax 0087 263A1D cmp bl,es:[di] 008A 74F7 je 0083 008C 2D0600 sub ax,0006 008F 90 nop 0090 90 nop 0091 90 nop 0092 90 nop *******************************************************************************