Консультация № 172204
15.09.2009, 17:30
0.00 руб.
0 2 1
Здравствуйте. Есть вопрос, связанный с портами клавиатуры. Ниже приведена небольшая резедентная программа. С помощью прерывания 60h считывается символ из порта, потом он сравнивается с другим символом(в моем случае 2), а далее в зависимости от сравнения идут разные сценарии. Меня интересует именно выделанная часть(насколько я знаю в конце прерывания надо еще дописать "завершение работы" с портом, да и само прерывание кривое), в которой не проиходит сравнение, тоесть в независимости от нажатой клавиши все идет по 1-му сценарию. В чем заключается моя ошибка? Возможно я просто неправильно оформил резидентную часть?

Код:
.model tiny
.code
org 2Ch
envseg dw ?
org 100h
begin:
old_int09h:
jmp short initialize
dw 0


int09h_handler proc far
in al,60h
cmp al,32h
je short re2

mov ah,2
mov dl,33h
int 21h
re2:
jmp dword ptr cs:old_int09h
int09h_handler endp

initialize proc near
mov ax,3509h
int 21h
mov word ptr old_int09h,bx
mov word ptr old_int09h+2,es
mov ax,2509h
mov dx,offset int09h_handler
int 21h
mov ah,49h
mov es,word ptr envseg
int 21h
mov dx,offset initialize
int 27h
initialize endp
end begin


Обсуждение

Неизвестный
15.09.2009, 18:30
общий
это ответ
Здравствуйте, Инов Сергей Игоревич.

Во-первых, с помощью команд
Код:

in al, 60h
cmp al, 32h
je short re2

вы ожидаете нажатия клавиши со скен-кодом 32h. Этот код соответствует клавише M. Если вы хотите отлавливать нажатие клавиши 2, то нужно сравнивать с числом 3 - это скен-код клавиши 2.

Во-вторых, мне не нравится вызов 21-го прерывания из обработчика. Да, в этот момент прерывания заблокированы, то есть не произойдет повторного вызова, но практика нехорошая.
В третьих, где сохранение регистров? Вы прерываете чужую программу. Она и знать не должна о том, что было прерывание! Вы же портите как минимум регистры AX и DL. Вообще-то этот пункт должен быть самым первым: никогда не изменяй регистры в обработчике аппаратного прерывания!

Насчет завершения прерывания беспокоиться как раз не нужно: вы передаете управление старому обработчику, который, во-первых, подтвердит получение кода из 60-го порта, во-вторых корректно завершит само прерывание.

Приложение:
.Model TINY
.Code

org 2Ch
envseg dw ?

.StartUp
old_int09h:
jmp short initialize
dw 0

int09h_handler proc far
push ax, dx
in al, 60h
cmp al, 03h
je short re2

mov ah, 2
mov dl, 33h
int 21h

re2:
pop dx, ax
jmp dword ptr cs:old_int09h

int09h_handler endp

initialize proc near
mov ax,3509h
int 21h
mov word ptr old_int09h,bx
mov word ptr old_int09h+2,es
mov ax,2509h
mov dx,offset int09h_handler
int 21h
mov ah,49h
mov es,word ptr envseg
int 21h
mov dx,offset initialize
int 27h
initialize endp
end
Неизвестный
16.09.2009, 16:23
общий
Спасибо, разобрался)

Еще кое что меня интересует, как заблокировтаь в обработчике нажатие клавиши? Я думаю сделать примерно так:
Код:
int09h_handler proc far
push ax, dx
in al, 60h
cmp al, 03h
je short re2

;Тут должна быть очистка буфера.

re2:
pop dx, ax
jmp dword ptr cs:old_int09h


Однаок не могу понять как очистить буфер, с помощью прерывания 21h не получается, выдает ошибку при запуске. Еще видел где то, что очистка идет при in al,60h , однако и этого не происходит.
Форма ответа