Septerra Core Legacy of the Creator

Такое сообщение выдают программы реального режима, откомпилированные в Borland Pascal 7.0 и использующие модуль CRT.TPU при попытке их запуска на компьютере с процессором PII-400 и выше. Для программ защищенного режима сообщение будет примерно такое: Runtime error 200 at XXXX:35D4. Ниже будет рассказано о причине возникновения этого сообщения и о том, как с ним бороться.
Я столкнулся с этой проблемой при переходе на новое "железо", когда отказался работать пакет программ, который до этого с 1994 года исправно работал на любой хбб-рухляди. Также невозможно было запустить всем известный hddspeed, пару-тройку других утилит и pascal-программы, использующие модуль crt. Ошибка возникала только на Celeron и Pentium II 400, 412, 448 и 533 MHz ;), на AMD K6-2 350 MHz все еще работало. После дизассемблирования программы и пары экспериментов с ВР причина была установлена - виновата процедура инициализации модуля CRT, которая определяет число проходов цикла с операциями sub и sbb, выполняемых процессором за одну миллисекунду: количество проходов цикла за один тик таймера (прошедшее число тиков хранится по адресу 0040:006С) делится на 55 MC(37h) - длительность одного тика. Результат используется затем в процедуре delay для задержки на нужное время циклом операций sub/sbb. Соответствующий фрагмент дизассемблированной SOURCER'ом программы выглядит так:

seg_a segment byte public
example proc far
start:
call far ptr sub_g_0000; инициализация модуля system
call far ptr sub_g_0548
call far ptr sub_e_OOOD; инициализация модуля crt
; далее следует код программы
example endp
seg_a ends

seg_e segment byte public ; в этом сегменте лежит crt
sub_e_000D proc far ; инициализация модуля crt
call sub_e_003B
retf
sub_e_OOOD endp
sub_e_003B proc near
mov bl,es:[di]
; es:[di]=40:6C -
; количество тиков таймера (каждый тик=55 мс)
mov ax,OFFE4h
cwd ; dx=FFFF ax=FFE4
call sub_e_02C6
not ax
not dx
mov cx,37h ; 55d
div сx ; Runtime error 200!
; здесь мы и вылетаем, т.к. результат не помещается в ах:
; ax=[dxax/cx] dx={dxax/cx}
mov ds:ticks_per ms.ax

retn
sub_e_003B endp
sub_e_02C6 proc near
; ждем заданного в b1 времени или пока dxax не FFFF FFFF
lос_е_02Сб:
sub ax, I
sbb dx, 0
jc ioc_ret_e_02D3
сmр bl,es:[di]
je loc_e_02C6
loc_ret_e_02D3:
retn
sub_e_02C6 endp

seg_e ends

end start

Так вот, результат div ex не помещается в ах, здесь и вылазит Runtime error 200. Теперь все желающие могут приглушить звук и внести необходимые исправления в модуль crt и готовые программы сами, а для остальных я могу рассказать о своих вариантах решения этой проблемы.

Первый способ - самый простой: забить nop'ами все ненужное, во многих программах с модулем crt delay не используется, и все сойдет с рук.

Второй способ немногим лучше: вместо деления непосредственно записывать в область данных некое произвольное число. Соответственно фрагмент
Р7 DO (not ax}
F7 D2 {not dx}
B9 37 00 {mov ex,00037}
F7 Fl {div ex}
A3???? {mov [????],ax}
можно заменить на
90 90 90 {пор пор пор}
90 90 90 {пор пор пор}
В8 FF FF {mov,ax,OFFFF}
A3???? {mov [????],ax}

Результат работает везде, но неправильно проходит задержка по delay: на PII задержка будет меньше, на более медленных машинах - больше, чем надо. Например, на Pentium 188MMX ;) задержка в полтора раза больше - delay (2000) ждет порядка трех секунд.

Третий способ, не до конца проверенный: в sub_e_003B, вместо mov сх,37h, писать mov cx,226h (550d) или 157Ch (5500d), тогда теоретически все будет работать правильно, только в delay будет задаваться время не в миллисекундах, а в десятках и сотнях миллисекунд соответственно. Этот вариант наиболее перспективен для исправления CRT.TPU в TURBO.TPL для последующей разработки в Borland Pascal программ, правильно работающих на всех процессорах.

Еще один теоретический вариант: можно попытаться в sub_e_02C6 sub ax,1 sbb dx,0 заменить на более медленные, занимающие больше тактов команды. Вот вроде и все, что я могу сказать по этому поводу. Любые поправки, дополнения, исправления приветствуются, т.к. автор не претендует на правильность и полноту освещения вопроса.
Хомяков В.Г.


Компьютерная газета. Статья была опубликована в номере 05 за 2000 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета