Написать собственное прерывание - Assembler
Формулировка задачи:
Здравствуйте!
Задание такое:
Нужно написать своё прерывание, генерируемое при нажатии клавиши Control+C.
Программа при нажатии должна напечатать сообщение на экране.
Я вроде программу написал, но она уходит в бесконечный цикл и не реагирует на ctrl+c;
В чем может быть проблема? Заранее спасибо!
Листинг программы
- Stk SEGMENT STACK
- DB 256 DUP(?)
- Stk ENDS
- DATA SEGMENT
- KEEP_CS DW 0 ; для хранения сегмента
- KEEP_IP DW 0 ; и смещения прерывания
- schet dw 0
- message db 'hello',10,13,'$'
- Message2 db 'prerivanie',10,13,'$' ;строка для сообщения
- DATA ENDS
- CODE SEGMENT
- ASSUME CS:CODE, DS:DATA, SS:Stk
- rout proc far ;начало процедуры
- push ax ;сохраняем все изменяемые регистры
- push dx ;сохраняем все изменяемые регистры
- mov ah,9h ;функция установки вектора
- mov dx,offset message2 ;в dx загружаем адрес сообщения Message2
- int 21h ;вывод строки на экран
- INC schet
- pop dx ;восстанавливаем регистры
- pop ax ;восстанавливаем регистры
- mov al,20h
- out 20h,al
- iret ;конец прерывания
- rout endp ;конец процедуры
- main proc far
- push ds
- sub ax,ax
- push ax
- mov ax,data
- mov ds,ax
- MOV AH, 35H ; функция получения вектора
- MOV AL, 23H ; номер вектора
- INT 21H
- MOV KEEP_IP, BX ; запоминание смещения
- MOV KEEP_CS, ES ; и сегмента
- push ds
- mov dx,offset rout ;смещение для процедуры в DX
- mov ax,seg rout ;cs ;сегмент процедуры
- mov ds,ax ;помещаем в ds
- mov ah,25h ;функция установки вектора
- mov al,23h ;номер вектора
- int 21h ;меняем прерывание
- pop ds ;восстанавливаем ds
- cickl_m:
- mov dx, offset message
- mov ah, 9
- int 21h
- cmp schet, 05h
- jb cickl_m
- CLI
- PUSH DS ;DS будет разрушен
- MOV DX,KEEP_IP;подготовка к восстановлению
- MOV AX,KEEP_CS ;
- MOV DS,AX ;подготовка к восстановлению
- MOV AH,25h ;функция установки вектора
- MOV AL,23h ;номер вектора
- INT 21h ;восстанавливаем вектор
- POP DS ;восстанавливаем DS
- STI
- ret
- Main endp
- code ends
- end Main
Решение задачи: «Написать собственное прерывание»
textual
Листинг программы
- ;FASM-code
- ;обработка CTRL+C
- ;------------------------
- org 100h
- jmp start
- mes1 db 13,10,'CTRL+C..',13,10
- start: mov ax,3301h ;включить CTRL+C
- mov dl,1 ;
- int 21h ;
- mov ax,2523h ;перехват его
- mov dx,new23 ;
- int 21h ;
- @inp: mov ah,1 ;считать/вывести символ с клавы..
- int 21h ;
- cmp al,27 ;ESC?
- jne @next ;нет
- ret ;да
- @next: jmp @inp ;продлжить, если не ESC и не CTRL+С..
- new23: mov si,mes1 ;иначе: обработчик INT-23h
- mov cx,12 ;
- @23: lodsb ;..просто выводит мессагу
- int 29h ;
- loop @23 ;
- iret ;выход из прерывания
Объяснение кода листинга программы
Список элементов кода на языке Assembler:
- org 100h - установка точки входа в программу
- jmp start - переход к метке start
- mes1 db 13,10,'CTRL+C..',13,10 - определение строки с сообщением
- start: mov ax,3301h - установка флага для обработки CTRL+C
- mov dl,1 - установка регистра dl в 1
- int 21h - вызов функции обработки прерывания
- mov ax,2523h - установка флага для перехвата прерывания
- mov dx,new23 - установка регистра dx для обращения к новому прерыванию
- int 21h - вызов функции обработки прерывания
- @inp: mov ah,1 - подготовка к чтению символа с клавиатуры
- int 21h - вызов функции обработки прерывания
- cmp al,27 - сравнение символа с клавишей ESC
- jne @next - если символ не равен ESC, перейти к следующей инструкции
- ret - выход из функции обработки прерывания
- @next: jmp @inp - повторение цикла, если символ не является ESC или CTRL+C
- new23: mov si,mes1 - установка регистра si для обращения к строке с сообщением
- mov cx,12 - установка регистра cx для подсчета количества выводимых символов
- @23: lodsb - чтение следующего символа из строки
- int 29h - вызов функции обработки прерывания для вывода символа
- loop @23 - повторение цикла до тех пор, пока не будет достигнут конец строки
- iret - выход из прерывания
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д