Micro #09
04 октября 1998
  TR-DOS  

Tape и Disk - Адаптация программ к системе TR-DOS (часть 3).

<b>Tape и Disk</b> - Адаптация программ к системе 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 к играм.

Анекдоты - парад анекдотов.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
COM-port & timer - Последовательный порт для Spectruma!!!
Coding - Новые 40 процедур: сдвиг атрибутов влево и вправо, вверх и вниз; сдвиг на один символ влево и вправо, вверх и вниз; сдвиг на один пиксел влево и вправо, вверх и вниз; Слияние картинок; Инвертирование экрана; Инвертирование символа вертикально и горизонтально; Вращение символа по часовой стрелке; Изменение атрибута; Смена атрибутов.
Письмо в LPRINT - Критика газеты LPRINT...

В этот день...   29 января