27.10.2013, 05:09
общий
это ответ
Здравствуйте, Посетитель - 397588!
Вот Вам переделанная программа, которая "по аналогии"
Полагаю, отличия найдете самостоятельно.
Будут вопросы, спрашивайте в мини-форуме.
[code h=200]
.model small
.data
old_kbd dd ?
string db "Laboratornaja rabota #2"
str_len=$-string
.stack 256
.code
bflag db 0 ;флаг нажатой клавиши ESC
main proc ;главная процедура
mov ax, @data
mov ds, ax ;настройка сегмента данных
CLI ;запрещаем все прерывания
;Перепрограммируем ведущий ПКП
mov cl, 0a0h ;процедура выполнения повторной инициализации
call reinit ;ведущего ПКП с базовым вектором 0a0h
;Сохраним старый вектор
mov ax, 35a1h
int 21h
mov word ptr old_kbd, bx ;сохраняем старый
mov word ptr old_kbd+2, es ;базовый адрес
;Запишим в таблицу адрес нашего обработчика прерывания
mov ax, 25a1h
mov dx, offset new_kbd
push ds
push cs
pop ds ;ds=cs настроили ds на начало сегмента кода
int 21h
pop ds ;вернем старое значение
;Запрет на уровне регистра маски всех прерываний кроме от клавиатуры
mov al, 11111101b
out 21h, al
STI
;Цикл ожидания нажатия клавиши ESC
m1:
mov al, cs:bflag
or al, al
jz m1
;восстанавливаем старый вектор
CLI
mov ax, 25a1h
push ds
lds dx, old_kbd
int 21h
pop ds
;Перепрограммируем ПКП в режиме по-умолчанию
mov cl, 08h
call reinit
mov al, 10111000b ;разрешены таймер, клавиатура, ведомый контроллер и НГМД
out 21h, al
STI
;Завершаем процедуру и передаем управление MS DOS
mov ax, 4c00h
int 21h
main endp
;Текст нового обработчика прерывания от клавиатуры
new_kbd proc far
push ax
push ds
push es
push di
push si
push cx
in al, 60h ;считываем из выходного порта контроллера
push ax
; разрешим дальнейшую обработку клавиатуры
in al, 61h ; читаем состояние клавиатуры
or al, 10000000b ; взводим бит 7
out 61h, al ; отправляем в порт
and al, 01111111b ; сбрасываем обратно бит 7
out 61h, al ; отправляем в порт
mov al, 20h ; сброс контроллера прерываний
out 20h, al
pop ax
cmp al, 01h ;клавиатуры скан-код клавиши ESC
jne m2
mov cs:bflag, al ;пометим, что была нажата ESC
m2:
test al, 80h
jnz kbd_ret
mov ax, @data
mov ds, ax
mov cx, str_len
lea si, string
m3:
lodsb
mov ah, 0eh
int 10h
loop m3
kbd_ret:
pop cx
pop si
pop di
pop es
pop ds
pop ax
iret
new_kbd endp
;Процедура инициализации ведущего ПКП
;Базовый адрес в процедуру передается через CL
reinit proc
mov al, 00010001b ;ICW1
out 20h, al
mov al, cl
out 21h, al
mov al, 00000100b ;ICW3
out 21h, al
mov al, 00001101b ;ICW4
out 21h, al
ret
reinit endp
end main[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен