Задание на обработчик прерываний - 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

Объяснение кода листинга программы

  1. xor ah,ah - инициализация регистра AH для последующего использования в качестве регистра-приемника
  2. int 16h - ожидание нажатия клавиши. Процессор переходит в режим 16 бит, затем выполняет команду INT 16h, которая вызывает BIOS-функцию обработки прерываний. В данном случае ожидается нажатие клавиши
  3. mov ax,2508h - сохранение текущего состояния регистра AX в переменную AX
  4. mov ds,SAVE_CS - сохранение текущего состояния регистра DS в переменную SAVE_CS
  5. mov dx,SAVE_IP - сохранение текущего состояния регистра DX в переменную SAVE_IP
  6. int 21h - восстановление вектора прерывания таймера. Процессор переходит в режим 16 бит, затем выполняет команду INT 21h, которая вызывает BIOS-функцию обработки прерываний. В данном случае восстанавливается вектор прерывания таймера
  7. mov ax,4C00h - загрузка кода завершения работы программы в регистр AX
  8. int 21h - завершение работы программы. Процессор переходит в режим 16 бит, затем выполняет команду INT 21h, которая вызывает BIOS-функцию обработки прерываний. В данном случае выполняется код завершения работы программы

ИИ поможет Вам:


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

Оцени полезность:

15   голосов , оценка 4.067 из 5
Похожие ответы