Перейти к основному содержимому

ЛР №6 Прерывания

Для кого этот документ

  • Студентам курса "Организация ЭВМ"
  • Необходимое ПО: Quartus II

Ввод/вывод информации в процессорной системе, в том числе с использованием прерываний

Цель работы: Изучить возможные способы ввода/вывода информации в процессорной системе.

Объекты изучения:

  • подсистема ввода-вывода процессора «NIOS II»
  • приложение Intel Monitor Program (IMP), по части работы с аппаратной составляющей процессорной системы

Планируемые результаты обучения

После выполнения этой работы студенты должны уметь:

  • Использовать кнопочные и ползунковые переключатели для ввода информации в процессорную систему
  • Выводить информацию из процессорной системы на красные, зеленые светодиоды, HEX индикаторы и LCD дисплей
  • Использовать прерывания в своих проектах для взаимодействия периферийных устройств с процессорной системой
  • Реализовывать в своих проектах порядок обработки прерываний, соответствующий требуемым приоритетам
  • Использовать в своих проектах программные прерывания
  • Эмулировать программно выполнение отдельных команд процессором

Исходные файлы лабораторной работы

В приложении приводится исходный код процедуры hex_display (Листинг 8) с подробными комментариями. Процедура отображает содержимое регистра r4 в шестнадцатеричном формате на 7-сегментных индикаторах.

Кроме того, там находится исходный файл тестовой программы interrupt_example.s (Листинг 9), демонстрирующей прерывания процессорной системы. В ней используются прерывания от таймера и кнопок.

Обработчик исключений, задачей которого является определение причины прерывания и вызов соответствующей процедуры, содержится в файле exception_handler.s (Листинг 10).

Обработчики прерываний от таймера и кнопок содержатся в файлах interval_timer.s (Листинг 11) и pushbutton_ISR.s (Листинг 12) соответственно.

Подготовка к лабораторной работе

Для выполнения лабораторной работы необходимо изучить по материалам лекций и предложенной литературе:

  1. Способы обмена информацией ЭВМ с периферийными устройствами
  2. Реализацию прерываний в процессорной системе NIOSII. Используемые для этого регистры процессора и портов ввода-вывода
  3. Назначение и принцип работы параллельных портов ввода вывода (PIO), используемых для подключения некоторых периферийных устройств к процессорной системе. Включите в отчет их краткое описание
  4. Уясните пример программы, приведенной в приложении, в которой используются прерывания, и уясните как реализован обработчик прерываний из описания процессорной системы «DE2-115 Media Computer» [6,7,3]. Вставьте в отчет его листинг программы
  5. Уясните пункты задания, выполняемого в текущей лабораторной работе, и напишите программные заготовки для их выполнения
  6. Уясните назначение команды trap. Вставьте в отчет ее формат и краткое описание. Напишите программную заготовку для выполнения пункта 5.1
  7. Уясните как выполняется команда mul. Вставьте в отчет ее формат и краткое описание. Напишите программу, которая будет эмулировать команду умножения

В лабораторной работе в качестве устройств ввода будут использоваться переключатели SWITCH и кнопки KEY3, KEY2, KEY1. В качестве устройств вывода – зеленые светодиоды LEDG 7..0, красные светодиоды LEDR 17..0, индикаторы шестнадцатеричной цифры HEX 7..0. Для связи с каждым устройством используются параллельные порты ввода/вывода (PIO). Адреса портов и принцип их работы приведены в описании процессорной системы [6,7,3].

В лабораторной работе решается задача последовательного сложения 8-разрядных чисел со знаком, которые задаются переключателями SWITCH 7..0. Набранное на переключателях число отображается на зеленых светодиодах. Вычисленная сумма сохраняется в одном из регистров, младшая часть которого отображается на красных светодиодах.

Вопросы для самоконтроля

  1. Для каких целей применяются прерывания в вычислительных машинах?
  2. Что называют системой прерывания в вычислительной машине?
  3. Относится ли система прерываний процессорной системы NIOS II к векторному типу?
  4. Какие аппаратные средства в используемой в лабораторных работах процессорной системе относятся к системе прерываний?
  5. Как можно запретить или разрешить прерывания текущей программы?
  6. Как можно выборочно запретить прерывания от отдельных устройств процессорной системы?
  7. Можно ли разрешить выборочно прерывания от отдельных кнопок в процессорной системе? Как это сделать?
  8. Какие прерывания относятся к аппаратным?
  9. Будет ли завершено выполнение текущей команды в момент прихода сигнала запроса прерывания от периферийного устройства?
  10. Как обеспечить корректное выполнение прерванной команды?
  11. Что называют исключениями (exception) в процессорной системе?
  12. Каким образом выполняется возврат из прерывания в процессорной системе?
  13. Какая команда вызывает программное прерывание?
  14. Что такое невыполнимая команда? Что произойдет, если в выполняемой программе окажется такая команда?

Порядок выполнения лабораторной работы

Часть 1. Программно управляемый ввод с переключателей и вывод на светодиоды

Используйте 8 правых переключателей SW 7..0 для задания вводимого числа и 8 зеленых светодиодов LEDG 7..0 для его отображения. Используйте 18 красных светодиодов LEDR 17..0 для отображения младших разрядов вычисленной суммы. Все эти устройства подключаются через параллельные порты к мультимедийной процессорной системе.

  1. Напишите программу на языке ассемблер, которая вначале обнуляет сумму, затем читает 8-разрядное значение (число со знаком в дополнительном коде), задаваемое переключателями SW 7..0, отображает прочитанное значение на зеленых светодиодах, выполняет сложение введенного числа с накопленной суммой, выводит сумму на красные светодиоды. Осуществляет переход на ввод очередного числа, выполняя бесконечный цикл.

  2. Создайте новую папку lab7_part и поместите в неё подготовленную программу.

  3. Используйте приложение IMP для создания нового проекта part1 в этой папке. Добавьте в проект Вашу программу и загрузите процессорную систему в кристалл ПЛИС. Выберите подходящую память для размещения Вашей программы. Разместите сегменты кода и данных, начиная с адреса 0х1000. Область в начале оперативной памяти понадобится в последующем для размещения обработчиков сброса и прерываний процессорной системы. Скомпилируйте и загрузите Вашу программу.

  4. Выполните программу по шагам, задавая различные значения вводимых чисел.

  5. Поставьте контрольную точку по адресу безусловного перехода на ввод очередного числа. Выполните рестарт программы. Убедитесь в ее работоспособности, каждый раз задавая новое число и нажимая кнопку продолжить. Запишите в отчет вводимые числа и наблюдаемые результаты.

  6. Удалите контрольную точку и вновь запустите программу. Наблюдайте поведение программы и поместите в отчет ваши объяснения.

Часть 2. Ввод информации с переключателей с опросом готовности

  1. Остановите выполнение программы. Наблюдайте состояние регистра данных и регистра захвата фронтов (edge-capture) PIO, соединенного с кнопками на стенде. Для этого используйте вкладку Memory приложения IMP. Включите опцию Query all devices, используя соответствующее окно. Сначала нажмите и удерживайте некоторые из кнопок (KEY3-KEY1), затем наблюдайте состояние регистров в окне Memory, затем нажмите кнопку Refresh в окне AMP и снова наблюдайте состояние регистров. Отпустите кнопки, наблюдайте состояние регистров, нажмите Refresh и снова наблюдайте. Уясните назначение регистров PIO и принцип их работы. Добавьте в отчет.

  2. Модифицируйте программу из предыдущей части таким образом, чтобы ввод очередного числа осуществлялся только после отпускания кнопки KEY3 на стенде. Используйте соответствующий разряд регистра edge-capture соответствующего PIO как сигнал готовности. Программа опрашивает его непрерывно до тех пор, пока он не установится. После ввода числа не забудьте снять сигнал готовности, записав нулевое значение в регистр edge-capture.

  3. Добавьте в проект файл с процедурой hex_display из приложения, используя команду Program Setting из меню Settings программы IMP. Процедура отображает содержимое 32-разрядного регистра процессора на 7-сегментных индикаторах HEX7-HEX0 в виде шестнадцатеричного числа.

  4. Модифицируйте программу из предыдущей части таким образом, чтобы накопленная сумма дополнительно отображалась на индикаторах HEX7-HEX0.

Часть 3. Ввод информации с переключателей в режиме прерывания

  1. Выполните задачу из предыдущей части. Используйте вместо опроса готовности устройства ввода формирование прерывания, которое инициируется нажатием кнопки KEY3 на стенде. Основная программа устанавливает все регистры, необходимые для формирования прерывания и выполняет бесконечный цикл. Программа обслуживания прерывания вводит число, вычисляет сумму и отображает ее на светодиодах и индикаторах.

  2. Проверьте экспериментально действия программы, выполняемые после формирования прерывания. Для этого поставьте контрольную точку по адресу обработчика прерываний (0x20). После достижения контрольной точки выполните программу по шагам. Фиксируйте в отчете Ваши наблюдения.

  3. Чтобы визуализировать работу основной программы, реализуйте в ней вывод на LCD дисплей Вашей фамилии, имени и отчества в режиме бегущей строки. Заготовку программы возьмите из 5 лабораторной работы. Рекомендуется оформить её в виде процедуры, которой в качестве параметра передается адрес в ОП выводимой текстовой строки через один из регистров процессора.

Часть 4. Реализация приоритетных прерываний

  1. Модифицируйте программу из предыдущей части таким образом, чтобы по кнопке KEY3 осуществлялось сложение нового числа с суммой, по кнопке KEY2 - вычитание нового числа из суммы, по кнопке KEY1 - обнуление суммы. Причем реализуйте приоритетность прерываний в соответствии с указанной последовательностью.

  2. Экспериментально определите действия программы при выполнении сброса процессорной системы. Для этого поставьте по нулевому адресу в ОП контрольную точку. Затем запустите программу и нажмите кнопку KEY0. Далее выполните программу по шагам. Фиксируйте в отчете Ваши наблюдения.

  3. Запрещайте прерывания от отдельных кнопок, изменяя содержимое регистра маски, соответствующего PIO.

  4. Разрешайте или запрещайте прерывания от кнопок, изменяя содержимое регистра ienable процессора. Для этого используйте прием из предыдущего пункта.

  5. Разрешайте или запрещайте прерывания от кнопок, изменяя содержимое бита pie регистра status процессора. Для этого используйте прием из пункта 4.3.

Часть 5. Программное прерывание trap и невыполнимые команды

  1. Вставьте в текст программы команду trap. Во вкладке disassembly посмотрите код этой команды и отразите в отчете. Экспериментально определите поведение программы при выполнении этой команды. Опишите в отчете. Модифицируйте обработчик прерываний таким образом, чтобы в случае обнаружения команды trap, он передал управление процедуре, которая выведет строку «trap» на экран LCD. Используйте для этого ранее выявленный код команды trap.

  2. Экспериментально определите поведение программы при выполнении команды mul (умножение). Проверьте, является ли эта команда невыполнимой в процессоре NIOS II и как система реагирует на попытку её выполнения. Перед выполнением команды в регистровом окне АМР задавайте различные значения сомножителей с использованием их знакового представления и наблюдайте результат в регистре r12.

  3. Для выполнения оставшихся пунктов задания следует использовать другую процессорную систему «DE 2-115 Basic Computer». В ней используется экономная версия (е) процессора NIOS II, в которой не поддерживается аппаратное выполнение команд умножения и деления. Выполните команду Settings > System settings. В появившемся окне следует указать используемую процессорную систему. Для этого в поле Select a system щелкните мышью по значку раскрытия списка. В появившемся списке выберите строку «DE2-70 Basic Computer» или «DE2-115 Basic Computer».

  4. Выполните загрузку выбранной процессорной системы в кристалл ПЛИС на стенде, используя команду Download System из меню Actions.

  5. Вставьте в текст программы рассмотренную в пункте 5.2 команду умножения. Экспериментально определите поведение программы при выполнении этой команды. Отразите в отчете. Следует напомнить, что во вновь установленной процессорной системе не поддерживается аппаратное умножение.

  6. Модифицируйте обработчик исключений таким образом, чтобы он передал управление процедуре, которая эмулирует выполнение команды mul. Для этого понадобится написать соответствующую процедуру.

Отчетные материалы

Отчетные материалы должны содержать:

  1. Цель лабораторной работы
  2. Материалы, связанные с подготовкой к работе, включая теоретическую часть и заготовку программы. Обязательно включите в отчет описание регистров, влияющих на прерывания процессора
  3. Информацию по выполнению каждого пункта задания. Причем в отчете должны содержаться выполняемые Вами действия, наблюдаемые результаты и Ваши объяснения
  4. Написанные фрагменты программ
  5. Краткое заключение

Примеры некоторых вопросов и заданий для защиты лабораторной работы

На защите студенты должны продемонстрировать умение использовать кнопки для прерывания текущей программы и выполнения ввода и вывода информации в процессорную систему.

Например, по кнопке Key 3 выполнить вывод младшего байта, задаваемого ползунковыми переключателями, на HEX0, по кнопке Key 2 выполнить вывод старшего байта, задаваемого ползунковыми переключателями, на HEX1, по кнопке Key 1 погасить индикаторы HEX1 и HEX0.

Дополнительные материалы


Приложение А

Рис. 6.1 – Регистры управления Nios II

Регистры управления Nios II

Рис. 6.2 – Регистры общего назначения процессора Nios II

Регистры общего назначения процессора Nios II

Исключения и прерывания в процессорной системе

Адрес сброса процессора Nios II в процессорной системе «DE2-70 Media Computer» установлен 0x00000000. Адрес, используемый для всех общих исключений и аппаратных прерываний – 0x00000020. Так как процессор Nios II использует один и тот же адрес для общих исключений и аппаратных прерываний, обработчик исключений должен определить источник исключения, анализируя соответствующий регистр состояния процессора. Таблица 6.1 содержит номера запросов прерываний IRQ для каждого устройства ввода/вывода в процессорной системе.

Таблица 6.1 Номера запросов прерываний от устройств ввода/вывода процессорной системы

Устройство ввода/вывода№ прерывания(IRQ)
Интервальный таймер0
Параллельный порт кнопок1
Аудиопорт6
PS/2 (для клавиатуры)7
PS/2 (для мыши)17
JTAG8
Последовательный порт10
Параллельный порт расширения JP111
Параллельный порт расширения JP212

Рис. 6.3 – Регистры параллельного порта ввода/вывода

Регистры параллельного порта ввода/вывода

Рис. 6.4 – Регистры параллельного порта ввода с кнопок

Регистры параллельного порта ввода с кнопок

Причины прерываний:

  • Аппаратное прерывание
  • Программная ловушка (команда trap): Команды trap и eret аналогичны командам call и ret, но используются для вызова/возврата из обработчика исключений.
  • Невыполнимая команда

Команда mul: mul (multiply registers) – умножение R типа (операнды в регистрах).


Приложение Б

Листинг 8

Исходный файл программы hex_display.s

.include "adress_map.s"

.text

.global hex_display
hex_display:
/* Сохранение регистров */
stw r11, (sp)
stw r10, -4(sp)
stw r3, -8(sp)
stw r2, -12(sp)
/* Адрес текущего индикатора */
movia r10, HEXL_ADDR
DISPLAY_LOOP:
/* Получаем цифру, с помощью маски */
andi r3, r2, 0xF
/* Получаем значение для отображения цифры на индикаторе */
movia r11, DECODE_TABLE
add r11, r11, r3
ldb r3, (r11)
/* Отображаем цифру */
stbio r3, (r10)
/* Выходим, если все цифры отображены */
movia r11, HEXH_ADDR + 3
beq r10, r11, DISPLAY_DONE
/* Сдвигаем слово вправо на 1 цифру */
srli r2, r2, 0x4
/* Получаем адрес следующего индикатора */
movia r11, HEXL_ADDR + 3
beq r10, r11, NEXT_REG_ADDR
/* Индикатор в текущем регистре */
addi r10, r10, 0x1
br DISPLAY_LOOP
NEXT_REG_ADDR:
/* Индикатор в следующем регистре */
movia r10, HEXH_ADDR
br DISPLAY_LOOP
DISPLAY_DONE:
/* Восставновление регистров */
ldw r11, (sp)
ldw r10, -4(sp)
ldw r3, -8(sp)
ldw r2, -12(sp)
ret


/* Таблица декодирования для 7-сегментных индикаторов. Каждый бит управляет 1 сегментом индикатора */

DECODE_TABLE:
.byte 0b00111111, 0b00000110, 0b01011011, 0b01001111
.byte 0b01100110, 0b01101101, 0b01111101, 0b00000111
.byte 0b01111111, 0b01101111, 0b01110111, 0b01111100
.byte 0b00111001, 0b01011110, 0b01111001, 0b01110001
.end

Листинг 9

Исходный файл программы interrupt_example.s

.equ    KEY1, 0
.equ KEY2, 1

/*******************************************************************
Эта программа демонстрирует использование прерываний на стенде
* DE2-115(70) Media Computer. Вначале запускается таймер, который генерирует
* прерывания каждые 33 мс. Затем разрешаются прерывания от таймера и кнопок.
* Процедура обработки прерывания таймера отображает текст на 7-сегментных
* индикаторах и сдвигает его влево или вправо. Направление сдвига определяется
* кнопками. При нажатии кнопки key1 текст сдвигается вправо, при нажатии
* key2 – влево, при нажатии key3 изменяется текст, используя данные с переключателей.
*******************************************************************/
.text
.global _start
_start:

movia sp, 0x03FFFFFC /* Определяем адрес вершины стека */
/* Определяем период срабатывания интервального таймера */
movia r16, 0x10002000
movia r12, 0x190000 /* 1/(50 MHz)x(0x190000) = 33 msec */
sthio r12, 8(r16) /*определяем младшее полуслово как стартовое значение*/
srli r12, r12, 16
sthio r12, 0xC(r16) /* старшее полуслово как стартовое значение */

/* Запускаем таймер и разрешаем прерывания от него */
movi r15, 0b0111 /* START = 1, CONT = 1, ITO = 1 */
sthio r15, 4(r16)

/* Разрешаем прерывания PIO, к которому подсоединены кнопки */
movia r15, 0x10000050 /* Адрес регистра кнопок */
movi r7, 0b01110
stwio r7, 8(r15) /* Устанавливаем 3 бита регистра маски прерывания*/

/* Разрешаем прерывания от отдельных устройств процессора */
movi r7, 0b011 /*Разрешаем прерывания от кнопок и таймера*/
wrctl ienable, r7
movi r7, 1
wrctl status, r7 /*Разрешаем прерывания текущей программы*/

IDLE:
br IDLE /* Бесконечный цикл */

.data
.global PATTERN
PATTERN:
.word 0x0000000F
.global KEY_PRESSED
KEY_PRESSED:
.word KEY2
.end

Листинг 10

Исходный файл программы exception_handler.s

/* СЕКЦИЯ СБРОСА "ax" требуется для того, чтобы определить секцию как исполняемую.AMP автоматически размещает секцию сброса по адресу, определяемому в настройках   процессора в SOPC Builder.*/
.section .reset, "ax"
movia r2, _start
jmp r2 /* Переходим в основную программу */

/***************************************************************************
СЕКЦИЯ ИСКЛЮЧЕНИЙ "ax" требуется для того, чтобы определить секцию как исполняемую.AMP автоматически размещает секцию исключений по адресу, определяемому в настройках процессора в SOPC Builder.
*****************************************************************************/

.section .exceptions, "ax"
.global EXCEPTION_HANDLER /*Определяем процедуру как глобальную*/
EXCEPTION_HANDLER: /*Процедура обработки прерываний*/
subi sp, sp, 16 /* Изменяем адрес указателя стека */
stw et, 0(sp) /*Сохраняем содержимое регистра et в стеке*/

rdctl et, ctl4 /* Сохраняем содержимое ipending в et */
beq et, r0, SKIP_EA_DEC /* Если прерывание не внешнее, то переходим на SKIP_EA_DEC */

subi ea, ea, 4 /* декрементируем регистр ea на 1 команду */
SKIP_EA_DEC:
stw ea, 4(sp) /* Сохраняем регистры в стеке */
stw ra, 8(sp)
stw r22, 12(sp)

rdctl et, ctl4
bne et, r0, CHECK_LEVEL_0 /* Если прерывание внешнее, то переходим на CHECK_LEVEL_0*/

NOT_EI: /* Прерывание произошло в случае встречи невыполнимой команды или команды TRAP */
br END_ISR /* Выходим из обработчика прерываний */
CHECK_LEVEL_0: /* Проверка, является ли прерывание прерыванием от таймера IRQ0 */
andi r22, et, 0b1
beq r22, r0, CHECK_LEVEL_1 /*Если бит 0b1 регистра et не равен 1, то переходим к проверке, является ли прерывание прерыванием от кнопок*/
call INTERVAL_TIMER_ISR /*Вызываем процедуру обработки прерывания от таймера*/
br END_ISR /*Выходим из обработчика прерываний*/

CHECK_LEVEL_1: /*Проверка, является ли прерывание прерыванием от кнопок IRQ1*/
andi r22, et, 0b10
beq r22, r0, END_ISR /* Если бит 0b10 регистра et не равен 10, то выходим из обработчика прерываний*/
call PUSHBUTTON_ISR /*Вызываем процедуру обработки прерываний от кнопок*/

END_ISR:
/* Восстанавливаем из стека все используемые регистры */
ldw et, 0(sp)
ldw ea, 4(sp)
ldw ra, 8(sp)
ldw r22, 12(sp)
addi sp, sp, 16
eret /*Выходим из процедуры обработки прерывания*/
.end

Листинг 11

Исходный файл программы interval_timer.s

.include "key_codes.s"              
.extern PATTERN
.extern KEY_PRESSED

/**** Процедура обработки прерываний от таймера ****/
.global INTERVAL_TIMER_ISR
INTERVAL_TIMER_ISR:
subi sp, sp, 40 /* Сохраняем регистры в стеке */
stw ra, 0(sp)
stw r4, 4(sp)
stw r5, 8(sp)
stw r6, 12(sp)
stw r8, 16(sp)
stw r10, 20(sp)
stw r20, 24(sp)
stw r21, 28(sp)
stw r22, 32(sp)
stw r23, 36(sp)

movia r10, 0x10002000
sthio r0, 0(r10)

movia r20, 0x10000020 /*адрес регистра HEX3_HEX0 */
movia r21, 0x10000030 /*адрес регистра HEX7_HEX4*/
addi r5, r0, 1
movia r22, PATTERN
movia r23, KEY_PRESSED

ldw r6, 0(r22) /* загружаем текст для вывода на 7-сегментные индикаторы */
stwio r6, 0(r20) /* выводим на HEX3 ... HEX0 */
stwio r6, 0(r21) /* выводим на HEX7 ... HEX4 */

ldw r4, 0(r23) /* Проверяем, какая кнопка была нажата */
movi r8, KEY1
beq r4, r8, LEFT /* Если была нажата key1, то сдвигаем текст вправо */
rol r6, r6, r5 /* иначе, сдвигаем влево */
br END_INTERVAL_TIMER_ISR
LEFT:
ror r6, r6, r5 /* сдвигаем текст вправо*/

END_INTERVAL_TIMER_ISR:
stw r6, 0(r22) /* выводим текст на 7-сегментные индикаторы */

ldw ra, 0(sp) /* Восстанавливаем регистры из стека */
ldw r4, 4(sp)
ldw r5, 8(sp)
ldw r6, 12(sp)
ldw r8, 16(sp)
ldw r10, 20(sp)
ldw r20, 24(sp)
ldw r21, 28(sp)
ldw r22, 32(sp)
ldw r23, 36(sp)
addi sp, sp, 40
ret
.end

Листинг 12

Исходный файл программы pushbutton_ISR.s

.include "key_codes.s"              
.extern KEY_PRESSED
.extern PATTERN

/**** Обработчик прерываний от кнопок ****/
.global PUSHBUTTON_ISR
PUSHBUTTON_ISR:
subi sp, sp, 20 /* Сохраняем регистры в стеке*/
stw ra, 0(sp)
stw r10, 4(sp)
stw r11, 8(sp)
stw r12, 12(sp)
stw r13, 16(sp)

movia r10, 0x10000050
ldwio r11, 0xC(r10) /* Считываем значение из edge-capture регистра*/
stwio r0, 0xC(r10) /* Сбрасываем прерывание */

movia r10, KEY_PRESSED
CHECK_KEY1:
andi r13, r11, 0b0010 /* Если была нажата кнопка key1 */
beq r13, zero, CHECK_KEY2
movi r12, KEY1
stw r12, 0(r10)
br END_PUSHBUTTON_ISR

CHECK_KEY2:
andi r13, r11, 0b0100 /* Если была нажата кнопка key2*/
beq r13, zero, DO_KEY3
movi r12, KEY2
stw r12, 0(r10)
br END_PUSHBUTTON_ISR

DO_KEY3:
movia r13, 0x10000040
ldwio r11, 0(r13) /* Считываем значение с переключателей */
movia r13, PATTERN
stw r11, 0(r13) /* Сохраняем измененный текст */

END_PUSHBUTTON_ISR:
ldw ra, 0(sp) /* Восстанавливаем регистры из стека */
ldw r10, 4(sp)
ldw r11, 8(sp)
ldw r12, 12(sp)
ldw r13, 16(sp)
addi sp, sp, 20
ret
.end

Чеклист выполнения

  • Работа выполнена
  • Отчет подготовлен