Иллюстрированный самоучитель по Assembler

Программирование аппаратных средств

Пример 3.12. Программирование мыши в режиме прерываний.

0.586; Будут команды новых процессоров
code segment use16; 16-разрядное приложение
assume CS: code,DS:code; Данные в сегменте команд
main proc
push CS; Настроим DS
pop DS; на сегмент команд
;Сохраним обработчик прерываний последовательного порта
mov AX,350Ch; Функция 35h, вектор 0Сh
int 21h
mov word ptr old_Oc,BX; Сохраним смещение
mov word ptr old_Oc+2,ES; Сохраним сегмент
;Установим наш обработчик прерываний последовательного порта
mov AX,25ОСb; Функция 25h, вектор 0Сh
mov DX,offset new_0c; Адрес нашего обработчика
int 21h
;Остановим программу функцией ввода с клавиатуры
mov AH,01h
int 21h
;Восстановим исходный обработчик драйвера мыши
mov AX,250Ch; Функция 25h, вектор 0Сh
Ids DX,old_0c; Сохраненный адрес
int 21h
mov AX,4C00h; Завершим программу
int 21h
main endp
new_0c proc
pusha; Сохраним все регистры
push DS; Сегментные регистры не
push ES; сохраняются командой pusha
mov DX,3F8h; Порт данных
in AL,DX; Прочитаем
cmp AL, 60h; Левая клавиша – код 60h
je Ibtn; Переход на отработку
cmp AL, 5Oh; Правая клавиша – код 5Oh
je rbtn; Переход на отработку
;Завершение обработчика прерываний
outret:pop ES; Восстановим сегментные
pop DS; регистры
mov AL,20h; Команда EOI
out 20h,AL; в контроллер прерываний
рора; Восстановим все регистры
iret; Выход из прерывания
;Если нажата левая клавиша мыши
Ibtn: mov АН, 1Eh; Атрибут символов желтый по синему
mov SI,offset msgdn; Адрес выводимой строки
jmp commn; На общую часть вывода
;Если нажата правая клавиша мыши
rbtn: mov AH,2Eh; Атрибут символов желтый по зеленому
mov SI,offset msgdn; Адрес выводимой строки
;Общая часть вывода на экран диагностической строки
commn: mov BX,OB800h; Настроим ES
mov ES,BX; на видеобуфер
push CS; Настроим DS
pop DS; на наш сегмент
mov CX,6; Число выводимых символов
mov DI,2000; Смещение на экране
cld; Движение вперед
scr: lodsb; АL=очередной символ
stosw; Из АХ на экран
loop scr; Цикл
jmp outret; После вывода завершить
;обработку прерывания
new_0c endp
old_0c dd 0; Ячейка для исходного вектора
msgdn db "Левая!"; Выводимые сообщения
msgup db "Правая"
code ends
stk segment stack
dw 128 dup(O)
stk ends
end main

Приведенный пример с точки зрения его структуры построен обычным образом. Исходное содержимое вектора 0Ch сохраняется в ячейке old_0c и используется перед завершением программы для восстановления вектора. Для упрощения установки обработчика прерываний программа написана без сегмента данных; ее немногие данные размещены в сегменте команд. Поскольку в начале программы регистр DS настраивается на сегмент команд, адресация к данным (в основной программе) возможна через DS.

Для того, чтобы можно было наблюдать обработку прерываний от мыши, основная программа после выполнения инициализирующих действий останавливается с помощью функции 01h DOS ожидания ввода символа с клавиатуры. После нажатия любой клавиши программа завершается, восстановив предварительно исходное состояние вектора последовательного порта.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.