Написать собственное прерывание - 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 - выход из прерывания
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д