
Разное / АВС. Код программы на ASM
.pdf.text
.global _start B _start
B SERVISE_UND // таблица векторов прерываний
B SERVISE_SVC // supervisor call B SERVISE_ABT_INST
B SERVISE_ABT_DATA
.word 0
B SERVISE_IRQ
B SERVISE_FIQ
_start:
1.MOV R1, #0b11010010 // запись в R1: режим IRQ, ARM-код, маски I и F MSR CPSR_c, R1 // содержимое R1 копируем в младший байт CPSR LDR SP, =0xFFFFFFFF-3 // устанавливаем стек для IRQ
MOV R1,#0b11010011 //запись в R1: режим SVC, ARM-код, маски I и F MSR CPSR_c, R1 // содержимое R1 копируем в младший байт CPSR LDR SP,=0x3FFFFFFF-3 // устанавливаем стек для SVC
BL CONFIG_GIC // вызов процедуры программирования GIC
LDR R0,=0xFF200050 // возврат из процедуры, установка адреса кнопок MOV R1, #0xF // запись в R1 разрешения на прерывание с кнопок
STR R1, [R0, #0x8] // установка разрешения в регистр прерывания порта MOV R0, #0b01010011 // запись в R0 режима SVC и снятия маски с I MSR CPSR_c, R0 // установка режима SVC и сброс маски I в CPSR IDLE: // основная программа
LDR R8,=0xFF20002 0 MOVW R9,#0x776E STR R9,[R8]
B IDLE SERVISE_UND: B SERVISE_UND SERVISE_SVC: B SERVISE_SVC
SERVISE_ABT_INST: B SERVISE_ABT_INST SERVISE_ABT_DATA:
B SERVISE_ABT_DATA
SERVISE_IRQ: // обработка по вектору IRQ PUSH {R0-R7, LR}
LDR R4,=0xFFFEC100 // начальный адрес регистров CPU-интерфейса
LDR R5, [R4, #0x0C] // считывание в R5 ID из регистра подтверждения
FPGA_IRQ1_HANDLER:
CMP R5, #73 // сравнение считанного ID c ID текущего запроса
UNEXPECTED:
BNE UNEXPECTED // случай несовпадения
BL KEY_ISR // выход на подпрограмму в случае совпадения
EXIT_IRQ: // метка открепления запроса
STR R5, [R4,#0x10] // копируем R5 в регистр окончания прерывания
POP {R0-R7, LR}
SUBS PC, LR,#4 // установка PC на точку продолжения программы
SERVISE_FIQ:
B SERVISE_FIQ
CONFIG_GIC: // начало процедуры программирования GIC PUSH {LR}
MOV R0, #73
MOV R1, #1
BL CONFIG_INTERRUPT // выход к программированию распределителя
LDR R0, =0xFFFEC100 // вход на CPUинтерфейс LDR R1, =0xFFFF
STR R1, [R0, #0x04] MOV R1, #1
STR R1, [R0]
LDR R0, =0xFFFED000 STR R1, [R0]
POP {PC} // выход из процедуры программирования GIC CONFIG_INTERRUPT: // программирование распределителя.
PUSH {R4-R5, LR} LSR R4, R0, #3 BIC R4, R4, #3
LDR R2,=0xFFFED100 ADD R4, R2, R4
AND R2, R0, #0x1F MOV R5, #1
LSL R2, R5, R2
LDR R3, [R4] ORR R3, R3, R2 STR R3, [R4] BIC R4, R0, #3
LDR R2,=0xFFFED800 ADD R4, R2, R4
AND R2, R0, #3
ADD R4, R2, R4
STRB R1, [R4]
POP {R4-R5, PC} // выход в CPU-интерфейс KEY_ISR:
LDR R0,=0xFF200050 // адрес кнопок
LDR R1, [R0,#0xC] // считывание состояние краевого захвата в R1 MOV R2, #0xF
STR R2, [R0,#0xC] // обнуление регистра краевого захвата
LDR R0,=0XFF200020 // адрес индикаторов CHECK_KEY0:
MOV R3, #0x1 // запись «1» в 0-й разряд
ANDS R3, R3 ,R1 // проверка установки краевого захвата в 0-м разряде BEQ CHECK_KEY1 // в случае отсутствия сканируем 1-й разряд
MOV R2, #0b00111111
STR R2,[R0] // вывод отображения «0» на индикатор B END_KEY_ISR // на выход из подпрограммы
CHECK_KEY1:
MOV R3, #0x2 // запись «1» в 1-й разряд
ANDS R3, R3, R1 // проверка установки краевого захвата в 1-м разряде BEQ CHECK_KEY2 // в случае отсутствия сканируем 2-й разряд
MOV R2,#0b00000110
STR R2, [R0] // вывод отображения «1» на индикатор B END_KEY_ISR // на выход из подпрограммы
CHECK_KEY2:
MOV R3, #0x4 // запись «1» во 2-й разряд
ANDS R3, R3, R1 BEQ IS_KEY3
MOV R2, #0b01011011 STR R2, [R0]
B END_KEY_ISR IS_KEY3:
MOV R2, #0b01001111 STR R2, [R0] END_KEY_ISR:
LDR R9,=0x40000000 // ставим задержку удержания отображения
DL: SUBS R9, R9, #1 BNE DL
MOV R2,#0
STR R2, [R0] // выключаем индикацию BX LR // выход из процедуры ( LR=>PC)
.end