В резидентном обработчике при нажатии ctrl-alt-del блокируется клавиатура(устанавливается в 1 переменная block_status) и выводится сообщение о блокировке, а при нажатии ctrl-alt-esc клавиатура разблокируется(переменная block_status устанавливается в 0) и сообщение о блокировке стирается. Так вот когда под досом запускаю прогу реакции на нажатия клавиш ни какой(на экране ничего не высвечивается и нет реакции на клавиши блокировки или разблокировки). Вот исходник: Код (Text): .model tiny prg segment para public 'code' assume cs:prg,ss:prg,es:prg,ds:prg org 100h ctrl_key equ 04h ;скан-коды клавиш alt_key equ 08h del_key equ 53h keyb_port equ 60h esc_key equ 01h EOI equ 20h PIC8259 equ 20h start: jmp setup ;установка резидентной программы int9_handler proc far sti pushf push ax push di push es L1: mov ax,40h ;проверка байта 0040:0017h mov es,ax mov di,17h mov ah,es:[di] ;в ah находится байт 0040:0017h pop es L2: test ah,ctrl_key ;нажата ли клавиша ctrl jz check_block ;нет? проверка на блокировку ;если да,то test ah,alt_key ;нажата ли клавиша alt jz check_block ;нет? проверка на блокировку ;да? проверка на нажатие esc check_esc: ;нажата ли клавиша esc in al,keyb_port cmp al,esc_key jne check_del ;нет? нажата ли delete push es mov bx,0B800h ;стирание сообщения mov es,bx mov di,1960 mov cx,40 clear: mov byte ptr es:[di],'' inc di inc di loop clear pop es xor ax,ax mov al,block_status ;обнуляем блокировку cmp al,0 je label1 mov al,0 mov block_status,al label1: jmp L6 check_del: ;нажата ли delete in al,keyb_port cmp al,del_key jne check_block push cs ;определение сегмента для message pop ds xor ax,ax mov ah,0Ch mov si,offset message push es mov bx,0B800h mov es,bx mov cx,40 mov di,1960 cld scr: lodsb stosw loop scr pop es xor ax,ax mov al,block_status cmp al,1 je label2 mov al,1 mov block_status,al label2: jmp L6 check_block: mov al,block_status cmp al,0 je process L6: pop di pop ax in al,61h mov ah,al or al,80h out 61h,al xchg ah,al out 61h,al mov al,EOI out PIC8259,al iret process: pop di pop ax popf jmp cs:[old_interrupt9] old_interrupt9 dd ? message db "Keyboard is blocked! To unblock it press$" block_status db 0 int9_handler endp end_ISR label byte setup: mov ax,3509h int 21h mov word ptr old_interrupt9,bx mov word ptr old_interrupt9+2,es mov ax,2509h mov dx,offset int9_handler int 21h mov ax,3100h mov dx,offset end_ISR mov cl,4 shr dx,cl inc dx int 21h prg ends end start
у тебя кстати доступ к block_status идет по умолчанию через DS, значение которого не определено на входе в ISR пиши явно cs:block_status чтоли тогда или добавь в начало push ds push cs pop ds и pop ds в конец
попробовал собрать это творение и отладить в Bochs. в принципе с моими поправками работает, только разблокируется почему-то не по Ctrl-Alt-Esc, а просто по альту =) И сообщение не выводится. зы. можно заменить на rep stosw ззы. зачем ты вначале сохраняешь в стеке ax & di, если используешь гораздо больше регистров?) лучше бы pusha сделал
Great Поисправлял. Блокирует клаву, выводит сообщение о блокировке. Но не разблокирует Код (Text): .model tiny .286 prg segment para public 'code' assume cs:prg,ss:prg,es:prg,ds:prg org 100h ctrl_key equ 04h ;скан-коды клавиш alt_key equ 08h del_key equ 53h keyb_port equ 60h esc_key equ 01h EOI equ 20h PIC8259 equ 20h start: jmp setup ;установка резидентной программы int9_handler proc far sti pushf pusha push ds push cs pop ds L1: mov ax,40h ;проверка байта 0040:0017h mov es,ax mov di,17h mov ah,es:[di] ;в ah находится байт 0040:0017h L2: test ah,ctrl_key ;нажата ли клавиша ctrl jz check_block ;нет? проверка на блокировку ;если да,то test ah,alt_key ;нажата ли клавиша alt jz check_block ;нет? проверка на блокировку ;да? проверка на нажатие esc check_esc: ;нажата ли клавиша esc in al,keyb_port cmp al,esc_key jne check_del ;нет? нажата ли delete xor ax,ax mov bx,0B800h ;стирание сообщения mov es,bx mov di,1960 mov cx,40 cld rep stosw xor ax,ax mov al,0 mov block_status,al jmp L6 check_del: ;нажата ли delete in al,keyb_port cmp al,del_key jne check_block xor ax,ax mov ah,0Ch mov si,offset message mov bx,0B800h mov es,bx mov cx,40 mov di,1960 cld scr: lodsb stosw loop scr xor ax,ax mov al,1 mov block_status,al jmp L6 check_block: mov al,block_status cmp al,0 je process L6: in al,61h mov ah,al or al,80h out 61h,al xchg ah,al out 61h,al mov al,EOI out PIC8259,al pop ds popa iret process: pop ds popa popf jmp cs:[old_interrupt9] old_interrupt9 dd ? message db "Keyboard is blocked! To unblock it press$" block_status db 0 int9_handler endp end_ISR label byte setup: mov ax,3509h int 21h mov word ptr old_interrupt9,bx mov word ptr old_interrupt9+2,es mov ax,2509h mov dx,offset int9_handler int 21h mov ax,3100h mov dx,offset end_ISR mov cl,4 shr dx,cl inc dx int 21h prg ends end start
я это дело минут 40 отлаживал с Bochs'е и химичил с обработкой. так и не понял почему, но у меня блокируется по Ctrl-Delete, а разблокируется по Ctrl- или Alt-Esc кстати можно заменить одной проверкой типа test ah, ctrl_key + alt_key
По моему что-то с сегментами не то. Но вот что именно не могу понять. Блокировать, блокирует, но вот с разблокировкой нифига не получается.
1) Предлагаю вначале вызвать старую int 9, пусть все-таки нажатие нормально обработает, и флаги в состоянии клавиатуры исправит 2) Будете вызывать int 21 в аппаратном обработчике - прямая догрога к глюкисам. Перепишите все без использования int 21.
Great Ок. Заранее спасибо. Ultrin Faern Не понимаю как после вызова в начале стандартного обработчика можно будет потом заблокировать клаву? Обьясните по подробней. Вы имеете ввиду этот кусок кода? Код (Text): setup: mov ax,3509h int 21h mov word ptr old_interrupt9,bx mov word ptr old_interrupt9+2,es mov ax,2509h mov dx,offset int9_handler int 21h mov ax,3100h mov dx,offset end_ISR mov cl,4 shr dx,cl inc dx int 21h prg ends end start В самом обработчике я не вызываю int21h.
Все, разобрался. Если кому-то интересно,то ошибка была в том, что в начале обработчика прерывания не нужно сохранять флаги. Об этом я узнал на одном форуме. Странно, но почему то в тех книгах, которые я читал об этом не было сказано ни слова.
кстати ты вначале делаешь Код (Text): sti pushf pusha а в одной из веток Код (Text): pop ds popa iret конечный код не противополжнен начальному. надо добавить popf перед iret'ом. или вообще выкинуть, как ты сказал, pushf.