From 652be8172d71f529c6c0ab555f16a3a7f996c617 Mon Sep 17 00:00:00 2001 From: Andrei Solodovnikov Date: Sat, 23 Nov 2024 17:42:36 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9B=D0=A010-11.=20=D0=98=D0=B7=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit При работе со стеком прерываний, верхушка стека не поднималась перед сохранением на стек новых данных, из-за чего данные сохранялись по нулевым ячейкам памяти. --- Labs/10. Interrupt subsystem/README.md | 48 ++++++++++++---------- Labs/11. Interrupt integration/program.mem | 4 +- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Labs/10. Interrupt subsystem/README.md b/Labs/10. Interrupt subsystem/README.md index 6d7e54a..f690e9a 100644 --- a/Labs/10. Interrupt subsystem/README.md +++ b/Labs/10. Interrupt subsystem/README.md @@ -234,7 +234,7 @@ _Рисунок 5. Структурная схема контроллера пр ```asm _start: # Инициализируем начальные значения регистров -00: li x2, 0x00003FFC # устанавливаем указатель на верхушку стека +00: li x2, 0x00003FF0 # устанавливаем указатель на верхушку стека 04: # данная псевдоинструкция будет разбита на две # инструкции: lui и addi @@ -282,30 +282,33 @@ main: # Сохраняем используемые регистры на стек trap_handler: 44: csrrw x5, mscratch, x5 # меняем местами mscratch и x5 -48: sw x6, 0(x5) # сохраняем x6 на стек mscratch -4С: sw x7, 4(x5) # сохраняем x7 на стек mscratch +48: addi x5, x5, -16 # поднимаем верхушку стека на 16 байт вверх + # (указатель на стек всегда должен быть выровнен + # границе в 16 байт) +4С: sw x6, 0(x5) # сохраняем x6 на стек mscratch +50: sw x7, 4(x5) # сохраняем x7 на стек mscratch # Проверяем произошло ли прерывание -50: csrr x6, mcause # x6 = mcause -54: li x7, 0x80000010 # загружаем в x7 код того, что произошло прерывание -58: # данная псевдоинструкция будет разбита на две +54: csrr x6, mcause # x6 = mcause +58: li x7, 0x80000010 # загружаем в x7 код того, что произошло прерывание +5С: # данная псевдоинструкция будет разбита на две # инструкции: lui и addi -5C: bne x6, x7, exc_handler # если коды не совпадают, переходим к проверке +60: bne x6, x7, exc_handler # если коды не совпадают, переходим к проверке # на исключение # Обработчик прерывания -60: lw x7, 0(x3) # загружаем переменную из памяти -64: addi x7, x7, 3 # прибавляем к значению 3 -68: sw x7, 0(x3) # возвращаем переменную в память -6C: j done # идем возвращать регистры и на выход +64: lw x7, 0(x3) # загружаем переменную из памяти +68: addi x7, x7, 3 # прибавляем к значению 3 +6С: sw x7, 0(x3) # возвращаем переменную в память +70: j done # идем возвращать регистры и на выход exc_handler: # Проверяем произошло ли исключение -70: li x7, 0x0000002 # загружаем в x7 код того, что произошло исключение -74: bne x6, x7, done # если это не оно, то выходим +74: li x7, 0x0000002 # загружаем в x7 код того, что произошло исключение +78: bne x6, x7, done # если это не оно, то выходим # Обработчик исключения -78: csrr x6, mepc # Узнаем значение PC (адреса инструкции, +7С: csrr x6, mepc # Узнаем значение PC (адреса инструкции, # вызвавшей исключение) -7C: lw x7, 0x0(x6) # Загружаем эту инструкцию в регистр x7. +80: lw x7, 0x0(x6) # Загружаем эту инструкцию в регистр x7. # В текущей микроархитектурной реализации это # невозможно, т.к. память инструкций отделена от # памяти данных и не участвует в выполнении @@ -319,18 +322,19 @@ exc_handler: # Проверяем произошло ли иск # Например, если это операция умножения — вызвать # подпрограмму умножения. -80: addi x6, x6, 4 # Увеличиваем значение PC на 4, чтобы после +84: addi x6, x6, 4 # Увеличиваем значение PC на 4, чтобы после # возврата не попасть на инструкцию, вызвавшую # исключение. -84: csrw mepc, x6 # Записываем обновленное значение PC в регистр mepc -88: j done # идем восстанавливать регистры со стека и на выход +88: csrw mepc, x6 # Записываем обновленное значение PC в регистр mepc +8С: j done # идем восстанавливать регистры со стека и на выход # Возвращаем регистры на места и выходим done: -8C: lw x6, 0(x5) # возвращаем x6 со стека -90: lw x7, 4(x5) # возвращаем x7 со стека -94: csrrw x5, mscratch, x5 # меняем обратно местами x5 и mscratch -98: mret # возвращаем управление программе (pc = mepc) +90: lw x6, 0(x5) # возвращаем x6 со стека +94: lw x7, 4(x5) # возвращаем x7 со стека +98: addi x5, x5, 16 # опускаем верхушку стека обратно на 16 байт вниз +9С: csrrw x5, mscratch, x5 # меняем обратно местами x5 и mscratch +A0: mret # возвращаем управление программе (pc = mepc) # что означает возврат в бесконечный цикл ``` diff --git a/Labs/11. Interrupt integration/program.mem b/Labs/11. Interrupt integration/program.mem index 280f2a2..6386966 100644 --- a/Labs/11. Interrupt integration/program.mem +++ b/Labs/11. Interrupt integration/program.mem @@ -1,5 +1,5 @@ 00004137 -FFC10113 +FF010113 00000193 04400293 00028293 @@ -16,6 +16,7 @@ FFC28293 00000073 00000063 340292F3 +ff028293 0062A023 0072A223 34202373 @@ -35,5 +36,6 @@ FFC28293 0040006F 0002A303 0042A383 +01028293 340292F3 30200073 \ No newline at end of file