ZX Review
#5-6
04 ноября 1997 |
|
Форум - Изучение и отладка @-файлов с помощью STS 5.1. Особенности отладки программ с помощью монитора STS. Исправление ошибки STS 5.1.
(c) Иван Рощин, г.Москва, 1997 Особенности отладки программ с помощью монитора STS Наверняка у каждого програм- миста при отладке своего творе- ния возникала мысль: хорошо бы в любой момент работы отлаживае- мой программы при нажатии опре- деленной комбинации клавиш вый- ти в отладчик (например, чтобы посмотреть значения переменных), а затем как ни в чем не бывало вернуться к выполнению програм- мы. В ZX-РЕВЮ уже были статьи на эту тему (например, на стр.244 за 1991г., на стр.33 за 1993г.). Здесь я хочу рассказать о приме- нении для этой цели наиболее популярного монитора-отладчика STS. В этом отладчике существует возможность поставить в отлажи- ваемой программе точку останова, при достижении которой происхо- дит выход в STS. Рассмотрим под- робнее, что происходит при уста- новке точки останова (с помощью клавиши "W"), и при выходе в STS, когда отлаживаемая програм- ма достигла точки останова. При установке точки останова: 1) Из ячеек ADR_W и ADR_W+1 бе- рется адрес предыдущей точки останова. 2) По этому адресу заносится со- держимое трех байтов памяти, ранее (при установке предыду- щей точки останова) запомнен- ных в ячейках ADR_B-ADR_B+2. 3) В ячейки ADR_W и ADR_W+1 за- сылается адрес, отмеченный курсором. 4) В ячейки ADR_B-ADR_B+2 зано- сится содержимое трех байтов памяти, начиная с адреса, от- меченного курсором. 5) По адресу, отмеченному курсо- ром, заносится команда JP ADR_OST. Когда выполняемая программа достигает точки останова: 1) Происходит переход на адрес ADR_OST, и управление пере- дается резидентной части STS. 2) STS запоминает содержимое всех регистров, режима преры- ваний и т.п. 3) Из ячеек ADR_W и ADR_W+1 бе- рется адрес точки останова. 4) По этому адресу заносится со- держимое трех байтов памяти, ранее (при установке этой точки останова) запомненных в ячейках ADR_B-ADR_B+2. 5) Вы можете работать в STS. Приведенной информации впол- не достаточно, чтобы написать фрагмент программы, который при нажатии некоторой комбинации клавиш (например, "SS+D" - от слова "Debugger") обеспечивает вход в STS с возможностью дальнейшего продолжения работы отлаживаемой программы. Нужно только знать адреса ADR_W, ADR_B и ADR_OST. Отмечу, что в разных версиях STS эти адреса разли- чаются, а адрес ADR_OST зависит еще и от расположения резидент- ной части STS в памяти. Чтобы найти ADR_OST, достаточно посмо- треть, какую команду STS поста- вит при нажатии клавиши 'W'. Чтобы найти ADR_B, можно, ска- жем, записать по какому-то адре- су памяти байты #AB,#CD,#EF, по- том поставить по этому адресу точку останова и найти адрес, по которому STS сохранил эти три байта. Чтобы найти ADR_W, нужно поставить по какому-нибудь адре- су (например, #8000) точку оста- нова, а потом посмотреть, где эти два байта (#00, #80) хранят- ся внутри STS. Привожу адреса для пяти из- вестных мне версий STS (при ус- ловии, что резидент находится по адресу #5B90): ADR_W ADR_B ADR_OST STS 3.2 #DFC3 #DFE4 #5B98 STS 3.3 #DFC3 #DFE4 #5B98 STS 4.1 #E064 #E07C #5B9B STS 4.3 #E06E #E088 #5B9B STS 5.1 #E02E #E038 #5B9B Приведенный ниже фрагмент вы можете вставить в отлаживаемую программу, например, после про- цедуры опроса клавиатуры или в другом часто выполняемом месте. Хочу заметить, что адрес его расположения в памяти должен быть меньше #C000, т.к. в этом фрагменте переключаются банки ОЗУ. 140. ADR_W EQU #E02E ;ЭТИ АДРЕСА ДАНЫ ДЛЯ ADR_B EQU #E038 ;STS ВЕРСИИ 5.1, ЕСЛИ РЕЗИДЕНТ ADR_OST EQU #5B9B ;НАХОДИТСЯ ПО АДРЕСУ #5B90. BANK_S EQU #1F ;БАНК STS BANK_D EQU #18 ;БАНК ОТЛАЖИВАЕМОЙ ПРОГРАММЫ LD BC,#7FFE ;АДРЕС ПОРТА КЛАВИАТУРЫ IN A,(C) ;ПРОВЕРЯЕМ, НАЖАТА ЛИ "SYMB.SHIFT" BIT 1,A ;ЕСЛИ ДА, ФЛАГ Z УСТАНОВЛЕН JR NZ,NEXT_C ;ЕСЛИ НЕ НАЖАТА, ВЫХОДИМ... LD B,#FD ;ИЗМЕНЯЕМ АДРЕС ПОРТА IN A,(C) ;АНАЛОГИЧНО ПРОВЕРЯЕМ BIT 2,A ;КЛАВИШУ "D". JR NZ,NEXT_C ;ЕСЛИ НЕ НАЖАТА, ВЫХОДИМ... LD BC,#7FFD ;УСТАНАВЛИВАЕМ БАНК, В LD A,BANK_S ;КОТОРОМ НАХОДИТСЯ STS. OUT (C),A 140. ;ИМИТИРУЕМ ДЛЯ STS ТОЧКУ ОСТАНОВА: LD HL,ADR_B ;ЗДЕСЬ ХРАНЯТСЯ 3 БАЙТА, ;ЗАПОМНЕННЫЕ ПРИ УСТАНОВКЕ ;ПРЕДЫДУЩЕЙ ТОЧКИ ОСТАНОВА. LD DE,(ADR_W) ;АДРЕС, ПО КОТОРОМУ ИХ НАДО ;РАЗМЕСТИТЬ (ОБЯЗАТЕЛЬНО НИЖЕ #C000)! LD BC,3 LDIR ;ВОССТАНАВЛИВАЕМ 3 БАЙТА LD HL,NEXT_C ;АДРЕС ПЕРВОЙ КОМАНДЫ, КОТОРАЯ LD (ADR_W),HL ;БУДЕТ ВЫПОЛНЕНА ПОСЛЕ ВЫХОДА ;ИЗ STS, ЗАПИСЫВАЕМ В ЯЧЕЙКИ ;ADR_W..ADR_W+1 (В НИХ STS ХРАНИТ ;АДРЕС, ПО КОТОРОМУ БЫЛА УСТАНОВЛЕНА ;ТОЧКА ОСТАНОВА). LD DE,ADR_B ;В ЯЧЕЙКАХ ADR_B..ADR_B+2 STS ХРАНИТ LD BC,3 ;3 БАЙТА, РАСПОЛОЖЕННЫЕ ПО АДРЕСУ LDIR ;ТОЧКИ ОСТАНОВА. LD A,BANK_D ;ВОЗВРАЩАЕМ БАНК, КОТОРЫЙ БЫЛ OUT (C),A ;ДО ЭТОГО. JP ADR_OST ;ТОЧКА ОСТАНОВА. NEXT_C ... ;ОТСЮДА НАЧНЕТСЯ ВЫПОЛНЕНИЕ ПОСЛЕ ;ВЫХОДА ИЗ STS. 2 После нажатия "SS+D" и выхо- да в STS все регистры принимают значения, которые были на момент прерывания программы, так что можно будет продолжить ее выпол- нение. В процессе отладки можно поставить в программе точку ос- танова, лишь бы в момент работы приведенного выше фрагмента (когда удаляется старая точка останова и ставится новая) адрес старой точки останова был ниже #C000. Вы можете продолжить выпол- нение отлаживаемой программы с того места, где она была оста- новлена, например, в пошаговом режиме ("SS+Z", "SS+X", "SS+T") или используя окно Trace, или с помощью комбинации клавиш "SS+J" (в версиях STS ниже 4.0 ис- пользуйте "J", установив адрес запуска равным содержимому PC, или используйте комбинацию "SS+K", но при этом останется экран STS). Если вы хотите вер- нуться в ассемблер, Бейсик или TR-DOS, используйте клавишу "Q". Если ваша программа зави- сает неизвестно почему, STS то- же может вам помочь. Для этого вы должны встроить фрагмент, по- добный описанному выше, в проце- дуру обработки прерываний 2-го рода. Предлагаю вашему вниманию уже готовую процедуру обработки прерываний, которая так же, как и описанная выше, проверяет факт нажатия "SS+D" и выходит в STS. После выхода из STS выполнение отлаживаемой программы будет продолжено с того места, где оно было прервано процедурой обра- ботки прерывания. Поэтому, нахо- дясь в STS, вы можете опреде- лить, какой фрагмент программы послужил причиной "зависания", по содержимому регистра PC. Ограничение на адрес распо- ложения процедуры в памяти та- кое же, как и у ранее описанно- го фрагмента. 140. ADR_W EQU #E02E ;ЭТИ АДРЕСА ДАНЫ ДЛЯ ADR_B EQU #E038 ;STS ВЕРСИИ 5.1, ЕСЛИ РЕЗИДЕНТ ADR_OST EQU #5B9B ;НАХОДИТСЯ ПО АДРЕСУ #5B90. BANK_S EQU #1F ;БАНК STS BANK_D EQU #18 ;БАНК ОТЛАЖИВАЕМОЙ ПРОГРАММЫ EX (SP),HL ;АДРЕС ВОЗВРАЩЕНИЯ ИЗ ПРЕРЫВАНИЯ LD (M1+1),HL ;ЗАПИСЫВАЕМ В ЯЧЕЙКИ M1+1 и M1+2 EX (SP),HL PUSH AF ;СОХРАНЯЕМ В СТЕКЕ PUSH BC ;ЗНАЧЕНИЯ РЕГИСТРОВ PUSH DE PUSH HL PUSH IX PUSH IY EXX EX AF,AF' PUSH AF PUSH BC PUSH DE PUSH HL CALL USER ;ЗДЕСЬ МОЖЕТ БЫТЬ ОПРОС ;КЛАВИАТУРЫ, ВЫЗОВ МУЗЫКИ, ;В ОБЩЕМ, ВСЕ ЧТО ХОТИТЕ. LD BC,#7FFE ;АДРЕС ПОРТА КЛАВИАТУРЫ IN A,(C) ;ПРОВЕРЯЕМ, НАЖАТА ЛИ "SYMB.SHIFT" BIT 1,A ;ЕСЛИ ДА, ФЛАГ Z УСТАНОВЛЕН JR NZ,NEXT_C ;ЕСЛИ НЕ НАЖАТА, ВЫХОДИМ... LD B,#FD ;ИЗМЕНЯЕМ АДРЕС ПОРТА IN A,(C) ;АНАЛОГИЧНО ПРОВЕРЯЕМ BIT 2,A ;КЛАВИШУ "D". JR NZ,NEXT_C ;ЕСЛИ НЕ НАЖАТА, ВЫХОДИМ... LD BC,#7FFD ;УСТАНАВЛИВАЕМ БАНК, В LD A,BANK_S ;КОТОРОМ НАХОДИТСЯ STS. OUT (C),A ;ИМИТИРУЕМ ДЛЯ STS ТОЧКУ ОСТАНОВА: LD HL,ADR_B ;ЗДЕСЬ ХРАНЯТСЯ 3 БАЙТА, ;ЗАПОМНЕННЫЕ ПРИ УСТАНОВКЕ ;ПРЕДЫДУЩЕЙ ТОЧКИ ОСТАНОВА. LD DE,(ADR_W) ;АДРЕС, ПО КОТОРОМУ ИХ НАДО ;РАЗМЕСТИТЬ LD BC,3 LDIR ;ВОССТАНАВЛИВАЕМ 3 БАЙТА M1 LD HL,0 ;АДРЕС ПЕРВОЙ КОМАНДЫ, КОТОРАЯ LD (ADR_W),HL ;БУДЕТ ВЫПОЛНЕНА ПОСЛЕ ВЫХОДА ;ИЗ STS, ЗАПИСЫВАЕМ В ЯЧЕЙКИ ;ADR_W..ADR_W+1 (В НИХ STS ХРАНИТ ;АДРЕС, ПО КОТОРОМУ БЫЛА УСТАНОВЛЕНА ;ТОЧКА ОСТАНОВА). LD DE,ADR_B ;В ЯЧЕЙКАХ ADR_B..ADR_B+2 STS ХРАНИТ LD BC,3 ;3 БАЙТА, РАСПОЛОЖЕННЫЕ ПО АДРЕСУ LDIR ;ТОЧКИ ОСТАНОВА. LD BC,#7FFD LD A,BANK_D ;ВОЗВРАЩАЕМ БАНК, КОТОРЫЙ БЫЛ OUT (C),A ;ДО ЭТОГО. POP HL ;ВОССТАНАВЛИВАЕМ POP DE ;ЗНАЧЕНИЯ РЕГИСТРОВ POP BC POP AF EXX EX AF,AF' POP IY POP IX POP HL POP DE POP BC POP AF EX (SP),HL ;УБИРАЕМ ИЗ СТЕКА POP HL ;АДРЕС ВОЗВРАТА EI JP ADR_OST ;ТОЧКА ОСТАНОВА. ;ПОСЛЕ ВЫХОДА ИЗ STS ВЫПОЛНЕНИЕ ПРОГРАММЫ БУДЕТ ;ПРОДОЛЖЕНО С ТОГО МЕСТА, ГДЕ ОНО БЫЛО ПРЕРВАНО ;ПРОЦЕДУРОЙ ОБРАБОТКИ ПРЕРЫВАНИЯ. NEXT_C ;ЕСЛИ ВЫЗОВ STS НЕ ПОНАДОБИЛСЯ: POP HL ;ВОССТАНАВЛИВАЕМ POP DE ;ЗНАЧЕНИЯ РЕГИСТРОВ POP BC POP AF EXX EX AF,AF' POP IY POP IX POP HL POP DE POP BC POP AF EI RET ;И ВЫХОДИМ ИЗ ПРЕРЫВАНИЯ. 2 При отладке программ часто используют совместно STS и ас- семблер (TASM, MASM, ZX ASM и т.п.), что очень удобно. Если в вашу программу встроен один из описанных выше фрагментов, вы должны обратить особое внимание на то, КАК вы запускаете прог- рамму на выполнение. Если из STS, все будет нормально в лю- бом случае. Если же программа запускается из ассемблера или BASIC'а, у вас может не полу- читься выйти в STS при нажатии "SS+D", или вы выйдете в STS, но не сможете продолжить выполне- ние программы. ─────────────── Известно, что пошаговое вы- полнение команд процессора в STS осуществляется тремя способами: с помощью комбинаций клавиш "SS+Z","SS+X" и "SS+T". Попробую рассказать об особенностях этих способов и о том, когда лучше использовать каждый из них: 1) "SS+Z" - происходит поша- говое выполнение команд про- цессора Z80. Никаких сложнос- тей при использовании "SS+Z" быть не должно, только не трассируйте команду HALT, когда запрещены прерывания - иначе компьютер зависнет. 2) "SS+X" - то же, что и "SS+ Z", но команда CALL будет вы- полнена непосредственно, без трассировки вызываемой под- программы, которая предпола- гается уже отлаженной. Это же касается и команды RST (кста- ти, в описании STS'а упомина- ется только CALL, а об RST нет ни слова). Выполняемая команда может находиться и в ОЗУ, и в ПЗУ. Это лучший спо- соб для выполнения отлаженных подпрограмм, но у него есть одна особенность: так как вы- зов подпрограммы происходит из резидента, в стек вместо адреса следующей выполняемой команды вашей программы будет занесен адрес для возврата в резидент. Почти всегда это не имеет никакого значения, но некоторые подпрограммы могут использовать содержимое сте- ка. Например, при отладке своих программ я часто ис- пользую подпрограмму, которая при своем вызове печатает на экране содержимое регистров процессора в момент вызова. Чтобы определить значение PC, она анализирует, какой адрес был занесен в стек при ее вы- зове. 3) "SS+T" - отладчик ставит после выполняемой команды, которая не может находиться в ПЗУ, точку останова и запус- кает отлаживаемую программу. По этой точке программа воз- вращается через резидент в STS. "SS+T" удобно применять для трассировки DJNZ, но для трасси- ровки подпрограмм (CALL, RST) лучше этот способ не использо- вать, т.к. может случиться не- приятность. Это видно на следую- щем примере: 140. #8000: CALL #8004 #8003: RET #8004: LD A,7 #8006: OUT 254,A #8008: RET 2 Эта программа должна устано- вить белый цвет бордюра. Если выполнить ее в пошаговом режиме с помощью "SS+Z", можно убе- диться, что именно это она и де- лает. Однако, если выполнить ее, нажав "SS+T", ожидаемого ре- зультата вы не получите. Для то- го, чтобы понять, почему это происходит, подробнее разберем алгоритм работы отладчика при нажатии "SS+T": - после текущей команды (в данном случае CALL #8004) ста- вится точка останова (команда JP, занимающая 3 байта). Бывшие на этом месте 3 байта запомина- ются. - передается управление по ад- ресу #8000; - при достижении точки остано- ва происходит возврат в отлад- чик, запомненные 3 байта восста- навливаются. Все бы хорошо, но в рассмат- риваемом случае 3 байта команды JP накладываются на адрес, по которому передается управление в команде CALL #8004. В результа- те этого реально выполняется следующая последовательность ко- манд: 140. #8000: CALL #8004 #8004: SBC A,E #8005: LD E,E #8006: OUT (254),A #8008: RET #8003: JP #5B9B 2 Разумеется, все вышесказан- ное относится и к команде про- цессора DJNZ, так что "SS+T" нужно применять с осторожностью. Вот, например, какая может быть ситуация при трассировке DJNZ: 140. #8000: LD B,#00 #8002: LD A,(#800A) #8005: OUT (#FE),A #8007: DJNZ #8002 #8009: RET #800A: DB 0 ;БАЙТ ИСПОРТИТСЯ 2 ─────────────── Теперь поговорим о пошаговой трассировке (окно Trace). В этом окне есть параметр Trace Call. Если он включен, отладчик будет заходить "внутрь" процедуры при каждом выполнении команды CALL или RST (эмулируется "SS+Z"), а если выключен - выполнять ее с помощью прямого запуска из рези- дента ("SS+X"). Мне кажется, бы- ла бы полезной возможность неза- висимо от значения Trace Call отключить трассировку подпрог- рамм, адреса которых выходят за заранее определенные границы. Эти границы должны указываться в окне Trace. Например, если ниж- няя граница равна #4000, а верх- няя #FFFF, то отладчик не будет заходить "внутрь" всех подпрог- рамм ПЗУ. Но так как этой воз- можности в STS нет, остается только надеяться, что она будет в одной из следующих версий. * * * (c) Иван Рощин, г.Москва, 1997 Исправление ошибки STS 5.1 В отладчике STS 5.1 есть ошибка, из-за которой нельзя нормально редактировать содержи- мое памяти в символьном виде. Рассмотрим пример: пусть по ад- ресу #8007 нужно поместить код символа "P": ┌────────────────────────────────────────┐ │#8000 00 00 00 00 00 00 00 00 ▒▒▒▒▒▒▒▒│ │#8008 00 00 00 00 00 00 00 00 ▒▒▒▒▒▒▒▒│ Входим в режим редактирования и указываем символ "P": ┌────────────────────────────────────────┐ │#8000 00 00 00 00 00 00 00 00 ▒▒▒▒▒▒▒P│ │#8008 00 00 00 00 00 00 00 00 ▒▒▒▒▒▒▒▒│ Но после нажатия 'ENTER' ожидае- мого результата не получим... ┌────────────────────────────────────────┐ │#8000 50 00 00 00 00 00 00 00 P▒▒▒▒▒▒▒│ │#8008 00 00 00 00 00 00 00 00 ▒▒▒▒▒▒▒▒│ Для исправления этой ошибки необходимо внести следующие из- менения в файл "sts5.1a": 140. - начиная с адреса #DE1C ввести команды: CALL #E681 NOP NOP NOP - по адресу #E67F поместить байты #2E,#00; - начиная с адреса #E681 ввести команды: JP Z,#E5BD OR C JP #E590 2 При этом приходится жертво- вать частью текстового сообщения "File exist, overwrite...", от которого в итоге останется лишь "File exist,over.". * * *
Другие статьи номера:
Похожие статьи:
В этот день... 4 октября