Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LAB4_W95.DOC
Скачиваний:
15
Добавлен:
16.04.2013
Размер:
176.13 Кб
Скачать

4.2.2. Программное прерывание swi.

Как было отмечено выше, SWIявляется программным прерыванием и инициируется программистом, в отличие от других прерываний, генерируемых аппаратурой микроконтроллера.SWIявляется немаскируемым, то есть его нельзя программно запретить.

Для генерации этого прерывания используется команда ассемблера SWI, при выполнении которой происходит следующее:

1. инкрементируется счетчик команд PC, в стеке сохраняется сначала младший, затем старший байтыPC;

2. в стеке последовательно сохраняются регистры X,A,C;

3. в счетчик команд заносятся два байта, хранящихся по адресам $1FFC, $1FFD.

Таким образом, после выполнения команды SWIуказатель стека смещается на пять байт в сторону младших адресов, и управление передается по вектору, записанному в ячейках $1FFC, $1FFD.

В качестве примера использования команды SWIрассмотрим программу вычисления факториала. Программу организуем следующим образом:

·с адреса $200 запишем блок начальной инициализации ячеек памяти и вызова подпрограммы обработки прерывания;

·с адреса $300 будет находиться собственно подпрограмма обработки прерывания, вычисляющая факториал;

·по адресу $400 поместим вспомогательную подпрограмму умножения двух чисел.

?в ячейке $50 разместим аргумент, а в ячейку $51 будем записывать результат (то есть факториал от содержимого ячейки $50).

Рассмотрим программу вычисления 4!

Основная программа :

200 LDA #$4 Записываем аргумент

202 STA $50 в ячейку $50.

204 LDA #$1 Записываем 1

206 STA $51 в ячейку $51.

208 RSP Устанавливаем указатель стека в $FF.

209 SWI Генерируем вызов подпрограммы обработки прерывания.

20À LDA $51 Записываем результат вычислений в регистрÀ.

20Ñ BRA $20Ñ Организуем бесконечный цикл.

Подпрограмма обработки прерывания :

300 LDA $50 Сравниваем аргумент

302 CMP #$1 с единицей.

304 BEQ $30Ñ Если аргумент равен единице, то переходим на $30С (вычисления окончены),

306 JSR $400 иначе вызываем подпрограмму умножения.

309 DEC $50 Уменьшаем аргумент на единицу.

30Â SWI Вызываем подпрограмму вычисления факториала.

30Ñ RTI Возврат из подпрограммы.

Подпрограмма умножения двух чисел :

400 LDA $50 Перемножаем два числа,

402 LDX $51 находящихся в ячейках $50 и $51

404 MUL Умножение

405 STA $51 Запоминаем результат.

407 RTS Возврат из подпрограммы.

Следующие несколько замечаний поясняют работу программы:

·при выполнении командыSWI, расположенной по адресу $209, в стеке сохраняются значения регистровPC,X,A,C, указатель стекаSPсмещается на 5 байт вниз, то есть в сторону младших адресов и управление передается по адресу, записанному в ячейках $1FFC (старший байт) и $1FFD (младший байт), где находится вектор программного прерывания (в данном случае - $300);

·поскольку вычисляется факториал с использованием рекурсии, то подпрограмма обработки прерывания будет иметь следующую структуру:

1. проверка условия завершения вычислений, возврат из подпрограммы в случае его истинности;

2. уменьшение аргумента на единицу и вложенный вызов этой же подпрограммы;

·при выполнении командыSWI, расположенной по адресу $30В, происходит вызов подпрограммы вычисления факториала от числа, на единицу меньшего, чем то, что хранится в ячейке $50; при этом регистры опять сохраняются в стеке, указатель стека смещается на 5 байт в сторону младших адресов, и управление передается по адресу, хранящемуся в ячейках $1FFC, $1FFD;

·задача вспомогательной подпрограммы умножения чисел - перемножить два числа, хранящихся в ячейках $50, $51 и поместить младший байт результата в ячейку $51;

Для правильной работы программы необходимо занести адрес подпрограммы обработки прерывания в ячейки $1FFC, $1FFD ($03 в $1FFC и $00 в $1FFD) и поставить точку останова по адресу $20C.

Запустите программу с адреса $200. На экране появится содержимое регистров микроконтроллера, причем регистр Aбудет содержать результат работы программы: число $18 (в десятичной системе счисления оно равно 24). Можно убедиться, что в ячейке $51 находится то же самое число.

Выведите на экран содержимое стека с адреса $C0 по адрес $FF. Напомним, что стек начинается с ячейки $FF и по мере заполнения растет вниз - в сторону младших адресов. Начиная с адреса $FF и ниже расположены 30 байт, которые были использованы программой в процессе работы. Каждый раз при выполнении команды SWIзанимаются очередные свободные пять ячеек памяти в стеке, а при выполнении командыRTIиз последних пяти использованных ячеек считываются значения регистров и указатель стека увеличивается на 5 байт, то есть занятая часть стека становится короче. После завершения работы программы стек полностью освобождается, указатель стека принимает то значение, которое он имел до запуска программы, но вся информация, сохраненная в свое время в стеке, остается. Убедитесь в этом.

При написании и отладке программ следует иметь ввиду, что стек может занимать максимум 64 байта (адреса $C0...$FF). Если происходит переполнение, то указатель стека циклически смещается на начало , что приводит к потере данных. Из вышесказанного следует, что для приведенного примера максимальное значение аргумента не должно превышать значения 10, в этом случае стек заполнится целиком. Однако, поскольку под результат отведен лишь один байт, то программа перестанет правильно работать уже при значении аргумента, равном 6. Избежать этого можно, предусмотрев в подпрограмме умножения чисел сохранение двухбайтного результата.

Соседние файлы в предмете Отладка микроконтроллеров ЭВМ