|
Micro
#09
04 октября 1998 |
|
Tape и Disk - Адаптация программ к системе TR-DOS (часть 3).

┌───────────────────────────────────────┐
│ Адаптация программ к системе TR-DOS │▒
└───────────────────────────────────────┘▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
ГЛАВА 3
=========================
= ЕЩЕ О БЕЙСИКЕ =
Программист, не знакомый с представле-
нием чисел бейсик-интерпретатором компью-
тера ZX Spectrum, немало удивится, стол-
кнувшись со следующей программой:
10 CLEAR 100
20 PAPER 27: INK 8E-12: BORDER 65536:CLS
30 PRINT AT -10000,22E22;"PLEASE WAIT"
40 LOAD ""CODE 0,0
50 RANDOMIZE USR 0
Такой программист будет настоятельно
утверждать,что этот бред написан не иначе,
как пациентом психиатрического учреждения,
до тех пор, пока не запустит программу и
не увидит результаты ее работы. Что про-
изойдет с программистом после того, как в
середине экрана появится надпись PLEASE
WAIT, затем загрузится и запустится игра,
предсказать трудно. Вероятнее всего, он
побежит в ПНД с предполагаемым диагнозом
"маниакально-депрессивный психоз на почве
программирования".
Для того чтобы с Вами этого не произо-
шло, раскрою Вам одну тайну. Все дело в
том, что при обработке чисел бейсик-интер-
претатор использует два их представления.
первое представление ─ это приятная для
глаз символьная форма, в которой число
16389, например, будет записано пятью бай-
тами согласно таблице ASCII. Однако такая
форма относительно долго обрабатывается
бейсик-интерпретатором, посему для своих
нужд он использует другое представление
числа ─ двоичное. Двоичная форма числа,
предваряемая префиксом ─ кодом 14 (0Eh),
хранится в памяти непосредственно после
символьной формы. Число 16389, например,
выглядит в памяти следующим образом:
│символьная форма│пре-│ двоичная │
│ 1 6 3 8 9 │фикс│ форма │
────┼──┬──┬──┬──┬────┼────┼─┬─┬─┬──┬─┼────
...│49│54│51│56│57 │ 14 │0│0│5│64│0│...
────┴──┴──┴──┴──┴────┴────┴─┴─┴─┴──┴─┴────
Отсюда видно, что двоичная форма числа
занимает 5 байт плюс байт префикса. При
записи целых констант в промежутке от 0 до
65535 "значащими" являются 3-й и 4-й байты
после префикса.В этом случае двоичную фор-
му числа можно первести в десятичную с по-
мощью оператора
PRINT PEEK (n+3)+256*PEEK (n+4)
- где n ─ адрес, по которому хранится байт
префикса.
Двоичная и символьная формы числа су-
ществуют параллельно. При выполнении ин-
струкций бейсик-интерпретатор руководству-
ется только двоичной формой, символьная
форма его не интересует, она сохраняется
ради удобочитаемости программ. Поэтому
"порча" символьного представления чисел
приводит в ужасный вид листинг программы,
но не влияет на её работоспособность.
Двоичная форма числа добавляется в мо-
мент проверки синтаксиса строки,то есть по
окончании набора строки и нажатии Enter.
При вызове на редактирование строки дво-
ичная форма удаляется, а после ввода ис-
правленной строки восстанавливается в со-
ответствии с новой редакцией.
Из сказанного должно быть понятно, что
загадочная программа, приведенная в начале
этой главы, не будет работать, если её
ввести с клавиатуры обычным способом, не
используя каких-либо специальных приёмов
(быть может, Вы уже пробовали её набрать и
запустить и решили, что не кто иной,как я,
и являюсь пациентом вышеуказанной клиники)
Для того,чтобы привести программу к та-
кому извращенному виду,при этом оставив её
работоспособной,необходимы внешние средст-
ва, например, монитор-отладчик STS5.1 или
подобные. Однако мы пока ведём разговор об
адаптации программ на диск,а не о приведе-
нии их в состояние алкогольного опъянения,
поэтому задачи у нас стоят обратные.
Можно было бы заняться пространным опи-
санием представления чисел в двоичной фор-
ме, но я предпочту дать практические сове-
ты по вычислению того, что скрыто под мас-
кой символьной формы.
Наиболее простым и эффективным способом
определения истинных значений чисел, по
моему опыту, является подстановка операто-
ра PRINT вместо операторов программы. В
этом случае все числа, используемые прог-
раммой, будут последовательно выведены на
экран в нормальном виде.
Если приведенную в начале главы прог-
рамму изменить следующим образом (обратите
внимание, что не использующие чисел опера-
торы и другие "лишние" символы заменены
пробелами, обозначенными в данном случае
знаком подчёркивания):
10 PRINT 100
20 PRINT 27:PRINT 8E-12:PRINT 65536:___
30 PRINT _-10000,22E22;________________
40 PRINT ___0,0
50 PRINT _0
- то в результате её выполнения на экране
появится:
24999
0
4
0
10 10
25000 40000
25000
0 OK, 50:1
Подставив полученные значения в програм-
му, получим привычный и понятный текст:
10 CLEAR 24999
20 PAPER 0: INK 4: BORDER 0: CLS
30 PRINT AT 10,10;"PLEASE WAIT"
40 LOAD ""CODE 25000,40000
50 RANDOMIZE USR 25000
Если Вы уже потянулись к клавише Edit,
чтобы побыстрее расставить операторы
PRINT, советую Вам прочесть всё с начала.
Как уже говорилось, при вызове на редакти-
рование двоичная форма числа безвозвратно
теряется, остаётся только символьная, и
если Вы исправите INK 8E-12 на PRINT 8E-12
с помощью бейсик-редактора, то и получите
не что иное, как 8E-12.Чтобы заменить опе-
раторы программы на PRINT,не "сломав" дво-
ичной формы чисел, нужны другие способы.
Можно воспользоваться всё тем же отладчи-
ком STS5.1; в крайнем случае сойдёт и опе-
ратор POKE. В этом тексте я не ставлю сво-
ей целью обучать работе с отладчиком, по-
этому расскажу лучше, как победить прог-
рамму без подручных средств.
Оператор POKE очень хорош, но только
тогда, когда знаешь, какие параметры долж-
ны следовать после него. А для этого нужно
заглянуть в память компьютера. Можно, на-
пример, воспользоваться строчкой, которая
выводит на экран адрес и содержимое ячеек
памяти и символьное представление этого
содержимого:
FOR n=23755 TO 4E10: PRINT n,PEEK n;
TAB 22;CHR$ (PEEK n*(PEEK n=32)): NEXT n
Выполнив эту строку, на экране получим:
23755 0 ? номер строки
23756 10 ?
23757 11 ? длина строки
23758 0 ?
23759 253 CLEAR ключевое слово
23760 49 1
23761 48 0 сим.форма параметра
23762 14 0
23763 14 ? префикс
23764 0 ?
23765 0 ?
23766 167 COS двоичная форма
параметра
23767 97 _
23768 0 ?
23769 13 ? возврат каретки
23770 0 ? номер строки
23771 20 ?
23772 38 &
23773 0 ?
23774 218 PAPER
23775 50 2
23776 55 7
scroll?
Теперь нужно внимательно изучить содер-
жимое экрана.
Как Вы уже знаете, первые два байта ─
это номер строки, далее ключевое слово
CLEAR, которое, собственно, нам и нужно.
Берём листок бумаги и карандаш и записыва-
ем адрес, по которому находится CLEAR(2375
9),и продолжаем сей высокоинтеллектуальный
труд. После CLEAR следует символьная форма
числа, затем двоичная, далее ─ символ
"возврат каретки" (конец строки), номер и
длина следующей строки и оператор PAPER.
Опять берём карандаш и записываем адрес
оператора PAPER.
Просмотрев программу до конца и записав
все адреса, которые необходимо заменить,
можно приступать к изменениям:
POKE 23759,245: REM Заменяем CLEAR
POKE 23774,245: REM Заменяем PAPER
POKE 23884,245: REM Заменяем INK
POKE 23997,245: REM Заменяем BORDER
POKE 24110,32: REM Заменяем CLS
POKE 24117,32: REM Заменяем AT
и т. д. Число 245 ─ это код ключевого сло-
ва PRINT, а 32 ─ код пробела.В данном при-
мере пробелами заменяются следующие опера-
торы и символы:
CLS
AT
"PLEASE WAIT"
""CODE
USR
Когда будут сделаны все необходимые из-
менения, просмотрите листинг программы,
дабы убедиться в том, что исправлено всё,
что нужно. Затем программу можно запустить
и изучать полученные результаты.
Иногда эту операцию можно несколько
упростить. Если в двоичном представлении
чисел используются целые константы от 0 до
65535, то определить их истинные значения
можно непосредственно при просмотре памя-
ти. Для этого желательно добавить к ка-
рандашу и бумаге калькулятор.
Найдите в памяти символьную форму чис-
ла, которое нужно "разоблачить"; за ней
следует префикс и двоичная форма.Если чис-
ло целое в промежутке от 0 до 65535, то
после префикса два нуля, затем два числа в
интервале от 0 до 255 и ещё один ноль.
Если это не так, то определённо можно ска-
зать, что число либо не целое,либо выходит
за пределы указанного диапазона. В этом
случае лучше прибегнуть к предыдущему спо-
собу. Если число "подходит", то умножьте
4-й после префикса байт на 256 и прибавьте
3-й. В рассматриваемом примере, чтобы по-
лучить параметр оператора CLEAR, нужно вы-
числить:
PRINT PEEK (23763+3)+256*PEEK (23763+4)
или
PRINT 167+256*97
Полученный результат (24999) и есть то,
что от нас пытались утаить.
Раскроем секрет ещё одного распростра-
нённого фокуса, основанного на знании фор-
мата чисел бейсик-интерпретатором (хотя,
возможно, отгадку Вы уже знаете).
Вам, наверняка, встречались подобные
строки:
10 CLEAR VAL "24999": INK VAL "7": PAPER
BIN: BORDER BIN
Таким образом программисты экономят опе-
ративную память. Как ни парадоксально, но
запись VAL "24999" занимает меньше места,
чем просто 24999. Так как в первом случае
число 24999 залкючено в кавычки,то оно яв-
ляется символьной строкой,а не числом и не
имеет после себя шести байт двоичного
представления. При выполнении функции VAL
эта строка переводится в число. Таким об-
разом экономится три байта. Что же касает-
ся BIN, то выигрыш ещё более очевиден.
Если вместо BIN подставить 0,то памяти бу-
дет занято на шесть байт больше, а резуль-
тат ─ тот же.
Этот способ экономии памяти несколько
замедляет выполнение программы,но его мож-
но и нужно использовать в загрузчиках, так
как именно они, как правило, наиболее кри-
тичны к размеру и не критичны к скорости
выполнения.
────────────────────────────
Продолжение будет...
------------------------------
В следующем номере Micro ищите главу 4
= ЗАГРУЗЧИКИ В МАШИННЫХ КОДАХ =
Для тех, кто не знает,
что такое машинный код.
..........................
Gloom Demons Inc. & Computer Eye
special for Micro 9.
08.10.98
Другие статьи номера:
Чемпионат - 1-й Запорожский Чемпионат по Вирусам. |
Tape и Disk - Адаптация программ к системе TR-DOS (часть 3). |
Chaos - описание игры "Хаос - битва волшебников". |
Полезные сведения - описание врагов из игры BARD'S TALE. |
Pokes - Poke's к играм. |
Анекдоты - парад анекдотов. |
Похожие статьи:
В этот день... 18 ноября