Задание на обработчик прерываний - Assembler
Формулировка задачи:
Задание: Дан массив A из 10 однобайтовых чисел. Перехватив прерывание от таймера, вывести на экран со сдвигом на один разряд влево только числа, содержащие четное количество единиц.
В качестве образца дали пример обработчика, который выводит секунды на экран. Объясните пожалуйста что и как делать.
Data segment
time dw 18 ;переменная таймера 18,2 сигнала в секунду (5 секунд - это 91 прерывания)
txt db " ", 13,10,"$"
cnt dw 10 ;для счетчика смещения
trii dw 0
SAVE_CS DW 0 ;сохраняем сегмент заменяемого прерывания
SAVE_IP DW 0 ;сохраняем смещение прерывания
Data ends
code segment
start: assume cs:code, ds: data, es:stk
mov AX, data
mov DS, AX ;сохраняем вектор - сохраняем исходные прерывания
mov AH, 25h ;функция получения вектора
mov AL, 8h ;номер вектора
int 21h ;
mov SAVE_IP, BX ;запоминаем смещение в BX
mov SAVE_CS, ES ;запоминаем сегмент в ES
push DS
mov DX,offset rout ;смещение для процедуры в DX
mov AX, seg rout ;помещаем сегмент процедуры в DS
mov DS, AX
mov AH, 25h ;в AH-> функцию установки вектора
mov AL, 8h ;в AL-> номер вектора
int 21h ;т.е. поменяли прерывание
pop DS
B:
jmp B
rout proc far
push AX ;сохраняем все измененные регистры
push DX
dec time
cmp time, 0
jnz nxt
dec cnt
mov AX, 18
mov time, AX
mov AX, trii
inc BX ;
mov CX, 1
add AX, CX
jc codeend
mov trii, AX
call PrintNumber ;вызов процедуры вывода на экран числа из AX
mov AH, 9h
lea DX, txt
int 21h
nxt:
pop DX
pop AX ;восстановили регистры
mov AL, 20h ;аппаратное прерывание
out 20h, AL ;
iret
rout endp
PrintNumber proc ;процедура показа числа из AX
push BX ;сохраняем содержимое регистров в стек, чтобы потом вернуть их
push DX
push SI
push CX
mov CX, 0 ;инициализируем цикл
mov BX, 10 ;в BX заносим основание системы счисления
loophere: ;основной цикл
mov DX, 0 ;обнуляем DX
div BX ;делим на 10
push AX ;результат в стеке
add DL, "0" ;конвертируем последнюю цифру в ASCII-код
pop AX ;вернем AX
push DX ;сохраним DX
inc CX ;увеличим CX на 1
cmp AX, 0 ;повторяем для всех цифр числа
jnz loophere
mov AH, 2 ;DOS-функция вывода символа
loophere2:
pop DX ;восстанавливаем цифры от последней к первой и
mov AH, 02h ;выводим их на экран
int 21h
loop loophere2
pop CX
pop SI
pop DX
pop BX
ret
PrintNumber endp
codeend: ;восстанавливаем исходный вектор
CLI
push DS
mov DX, SAVE_IP
mov AX, SAVE_CS
mov DS, AX
mov AH, 25h
mov AL, 1ch
int 21h
pop DS
STI
mov AX, 4ch
int 21h
code ends
stk segment stack
db 256 dup ("*")
stk ends
end startРешение задачи: «Задание на обработчик прерываний»
textual
Листинг программы
xor ah,ah int 16h ; ждём нажатия клавиши mov ax,2508h mov ds,SAVE_CS mov dx,SAVE_IP int 21h ; восстанавливаем вектор прерывания таймера mov ax,4C00h int 21h
Объяснение кода листинга программы
xor ah,ah- инициализация регистра AH для последующего использования в качестве регистра-приемникаint 16h- ожидание нажатия клавиши. Процессор переходит в режим 16 бит, затем выполняет команду INT 16h, которая вызывает BIOS-функцию обработки прерываний. В данном случае ожидается нажатие клавишиmov ax,2508h- сохранение текущего состояния регистра AX в переменную AXmov ds,SAVE_CS- сохранение текущего состояния регистра DS в переменную SAVE_CSmov dx,SAVE_IP- сохранение текущего состояния регистра DX в переменную SAVE_IPint 21h- восстановление вектора прерывания таймера. Процессор переходит в режим 16 бит, затем выполняет команду INT 21h, которая вызывает BIOS-функцию обработки прерываний. В данном случае восстанавливается вектор прерывания таймераmov ax,4C00h- загрузка кода завершения работы программы в регистр AXint 21h- завершение работы программы. Процессор переходит в режим 16 бит, затем выполняет команду INT 21h, которая вызывает BIOS-функцию обработки прерываний. В данном случае выполняется код завершения работы программы