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 к играм. |
Анекдоты - парад анекдотов. |
Похожие статьи:
В этот день... 13 декабря