Д И А Л О Г Л Р О Г Р А М М И С T Q B
Б .К У Р И Ц Ы Н ,
257010, Украина,
г.Черкассы-10, а/я 1529.
ПЕРЕХВАТ
СИСТЕМНЫХ
СШИБОК
ПРИ
П
РОГРАММИ РОВ АН И
И
НА АССЕМБЛЕРЕ
ДЛЯ КОМПЬЮТЕРОВ
"ZX-SPECTRUM"
В последнее время программисты, пишущие для “ZX-Spectrum”,
“выросли из пеленок” и стали создавать программы, которые дока-
зывают что “ZX-Spectrum” — это компьютер, на котором можно не
только играть в увлекательные игры, но и продуктивно выполнять
обработку текстов и другие работы.
Важную роль при этом играет не столько универсальность про-
грамм (чего трудно ожидать от ограниченных ресурсов Speccy),
сколько профессиональность их написания и надежность.
По своему опыту знаю, что часто на пути к доведению программы
до профессионального уровня перед многими программистами вста-
ет проблема перехвата системных ошибок (особых ситуаций). В дан-
ной статье рассмотрена концепция системной ошибки и методика ее
перехвата.
Что же такое особая ситуация? Это исключительно удобный и эф-
фективный программный механизм для разграничения в программе
общего хода вычислений и обработки всех ограничений, которые эти
вычисления делают невозможными, ограничивают или видоизменя-
ют. Термин “особая ситуация” больше отвечает сути понятия, чем “си-
стемная ошибка”. В англоязычной литературе применяется термин
“Exception” — “Исключение”, которым мы и будем пользоваться.
В ряд ограничений общего хода вычислительного процесса могут
входить недостаток динамической памяти, любые арифметические
ошибки (переполнение порядка, деление на ноль и т.п.), ошибка за-
грузки с внешнего устройства и множество других подобных ситуа-
ций. Более того, исключение может инициироваться самой про-
граммой для себя же.
Когда вы работаете в Бейсике и получаете сообщение типа “BREAK-
CONT repeats” или “Таре loading error” или даже просто “ Ok” — знай-
те, что сообщение было выдано обработчиком исключений. Даже пре-
дупреждающий писк, который вы услышите, если введете неверную
команду — тоже результат обработки исключения. Вообще, вся работа
процедур ПЗУ “ZX-Spectrum” построена на механизме исключений. В
этих условиях построение своих программ на том же механизме выгля-
дит логичным и оказывается весьма удобным.
Каков же этот механизм?
Любая программа пишется как подпрограмма, т.е. выход из нее
осуществляется командой RET. Поэтому у каждой программы-на-
следника есть предок — некоторая другая вызвавшая ее подпрограм-
ма. Наследник выполняет определенные функции, после чего завер-
шается, возвращая управление предку командой RET. Если наслед-
ник не смог выполнить свою функцию, он генерирует исключение,
которое автоматически прерывает ход программы и передает управ-
ление обработчику исключений, который установлен подпрограм-
мой-предком. Номер исключения конкретизирует проблему наслед-
ника, из-за которой функция оказалась невыполненной.
Исключение генерируется командой ассемблера:
RST8
;прерывание исключения
DEFB ExcNum
;номер исключения
Выбор номеров исключений является частным делом программи-
ста , если он не собирается отдавать на обработку Бейсик-системе ни
одного исключения. В противном случае пространство номеров иск-
12
Радиолюбитель 10/94
лючений системы (-1 .
..26) лучше не перекрывать.
По команде RST 8 выполняются некоторые системные действия
(ExcNum записывается в ErrNr, сбрасывается память и стек калькулято-
ра) . Для нас же самое важное — что сбрасывается стек процессора и вы-
полняется переходк обработчику исключений по адресу ((ErrSP)) —т.е.
“дважды косвенно”. Собственно адрес обработчика лежит на дне стека, а
системная переменная ErrSP указывает на дно. Поэтому переход к обра-
ботчику выполняется в прерывании RST 8 таким образом:
LD SP, (ErrSP)
;опустошение стека
RET
;переход к обработчику
Задача обработчика — проанализировать номер исключения, ко-
торый хранится в системной переменной ErrNr (адрес # 5 СЗА или
(IY), если регистр IY содержит это стандартное значение) и обрабо-
тать те исключительные ситуации, которые касаются подпрограм-
мы-предка, которой и принадлежит этот обработчик исключений.
Другие исключения должны быть переданы предку предка и т.д.
Легко понять, почему сбрасывается стек. Произошло исключение,
возврат по RET к предку недопустим, т.к. наследник не смог выпол-
нить то, что от него требовалось. А значит, недопустим возврат к пре-
дку предка и т.д.
Для того, чтобы терялась только недействительная после исклю-
чения часть стека (та часть, которая “наросла” после установки по-
следнего обработчика исключений), его установка выполняется со-
вместно с операцией, которую, по аналогии с процессором 1801ВМ1,
можно назвать маркированием стека.
Маркирование стека производится следующим образом:
LD HL, (23613) ;содержимое ErrSP — адрес дна стека
PUSH HL
сохраняем ErrSP на этом же стеке
LD HL
; адрес обработчика исключений
PUSH HL
;это новое дно стека
LD (23613) ,SP ;новый пустой стек создан
Теперь в случае исключения разрушится вновь созданный стек и
будет запущен обработчик исключений, указанный при его созда-
нии. Этот обработчик первым делом восстановит старый стек:
LDSP,(23613)
;опустошить стек
POP HL
;это адрес обработчика исключений
POP HL
;это сохраненный ранее ErrSp
LD (23613) ,HL ;восстанавливаем значение ErrSP
Затем он проанализирует номер исключения и выполнит необхо-
димые действия. Ошибки, которые он не обслуживает, распостраня-
ются дальше по уровням вложенности подпрограмм. Это распостра-
нение делается так:
LD A, (IY)
;номер исключения
LD (ЕХС) ,А
RST 8
;имитируем его появление
ЕХС:
DEFB 0
Далее представлены рабочие процедуры для маркирования стека.
Маркирование стека и установка обработчика исключений:
;вход: DE — адрес обработчика
;HL,IX — разрушаются
MARK:
POP IX
LDHL, (23613)
PUSH HL
PUSH DE
LD (23613) ,SP
JP (IX)
;Демаркировка стека и снятие обработчика исключений;
;HL,IX — разрушаются
UNMARK:
POP IX
LDSP,(23613)
POP HL
POP HL
LD (23613),HL
JP (IX)
;Распостранить исключение, номер которого находится в ErrNr;
; (модуль только для обработчика исключений,
предыдущая страница 13 Радиолюбитель 1994-10 читать онлайн следующая страница 15 Радиолюбитель 1994-10 читать онлайн Домой Выключить/включить текст