Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ASM_lectures.doc
Скачиваний:
27
Добавлен:
28.04.2019
Размер:
992.77 Кб
Скачать

Резидентный обработчик прерываний от клавиатуры с подключением как до, так и после системного.

Иногда удобно некоторую часть обработки выполнить до системного обработчика, а некоторую часть после.

При получении управления, наш обработчик запоминает в ячейке tail содержимое хвостового указателя. Затем управление передается в системный обработчик. После возврата из системного обработчика, сохраненное содержимое хвостового указателя сравнивается с текущим значением, полученным из ячейки 40h:1Ch. Если системный обработчик не сместил хвостовой указатель, это значит, что была нажата какая-то управляемая клавиша (Shift),(Alt) и т.д. В этом случае необходимость в дальнейшем анализе отсутствует. Если указатель сместился, то в буфер был введен очередной код, который, очевидно, помещен в буфер по адресу, сохраненному в ячейке tail.

Таким образом, предыдущая программа написана не совсем корректно. В ней не рассматривалась возможность наличия управляемых клавиш, которые ничего не заносят в буфер. Нажатие управляемых клавиш приведет к тому, что предыдущая программа снова проанализирует предыдущий символ, который скорее всего был проанализирован ранее. Правда, такой повторный анализ не приведет к ошибке.

Если использовать в резидентной программе регистр DS, то каждая команда с адресацией к памяти получается на один байт короче, т.к. будет отсутствовать байт префикса замены регистра.

CODE_SEG SEGMENT

ASSUME CS:CODE_SEG,DS:code_seg

ORG 100H

START:

JMP BEGIN

int_2Fh_vector DD ?

old_09h DD ?

tail DW 0

;=============================================================================

;

;=============================================================================

new_09h proc far

push AX

push ES

mov AX,40h ; Настроим ES на сегментный

mov ES,AX ; адрес области данных BIOS

mov AX,ES:[1Ch] ; Сохраним адрес хвоста перед обработкой

mov CS:tail,AX

pop ES

pop AX

pushf ; В системный обработчик

call CS:old_09h ; с возвратом

push AX

push BX

push ES

mov AX,40h ; Настроим ES на сегментный

mov ES,AX ; адрес области данных BIOS

mov BX,CS:tail ; Адрес нового хвоста

cmp BX,ES:[1Ch] ; Хвост сместился?

je go_out ; нет – на выход

mov AX,ES:[BX] ; Получим последний символ из буфера

cmp AX,1600h ; Был введен расширенный код ASCII сочетания Alt/U?

jne go_out ; Нет

mov word PTR ES:[BX],OODAh ; Да, заменим код в буфере на код уголка

go_out:

pop ES

pop BX

pop AX

iret

new_09h endp

;=============================================================================

;

;=============================================================================

int_2Fh proc far

cmp AX,OC700h

jne pass_2Fh

mov AL,OFFh

iret

pass_2Fh:

jmp dword PTR CS:[int_2Fh_vector]

int_2Fh endp

;=============================================================================

;

;=============================================================================

begin:

mov AX,OC700h ; AH=OC7h номер процесса C7h

; AL=OOh -дать статус установки процесса

int 2Fh ; мультиплексное прерывание

cmp AL, 0

jz not_installed ; возвращает AL=0 если не установлена

lea DX,msg

call print

int 20h

msg DB 'Уже установлена',13,10,'$'

not_instailed:

mov AX,352Fh ; получить вектор

int 21h ; прерывания 2Fh

mov word ptr int_2Fh_vector,BX ; ES:BX - вектор

mov word ptr int_2Fh_vector+2,ES

mov DX,offset int_2Fh ; получить смещение точки входа в новый

; обработчик на DX

mov AX,252Fh ; функция установки прерывания

; изменить вектор 2Fh

int 21h ; AL - номер прерыв. DS:DX - указатель программы обработки прер.

mov AX,3509h ; получить вектор

int 21h ; прерывания 09h

mov word ptr old_09h,BX ; ES:BX - вектор

mov word ptr old_09h+2,ES ;

mov DX,offset new_09h ; получить смещение точки входа в новый

; обработчик на DX

mov AX,2509h ; функция установки прерывания

; изменить вектор 09h

int 21h ; AL - номер прерыв. DS:DX - указатель программы обработки прер.

;------------------------------------------------------------------------------

mov DX,offset begin ; оставить программу ...

int 27h ; ... резидентной и выйти

;=============================================================================

;

;=============================================================================

PRINT PROC NEAR

MOV АН,09H

INT 21H

RET

PRINT ENDP

;=============================================================================

CODE_SEG ENDS

END START

В командах, где обращение выполняется по абсолютному адресу, необходимо указывать обозначение сегментного регистра. Так, командуя

mov AX,1ch

засылает в АХ число 1сh (квадратные скобки не определяют косвенную адресацию), в то время, как, командуя

mov AX DS: 1ch

загружает в АХ содержимое слова памяти расположенного по адресу DS:1ch.

Указание регистра DS в программной строке не приводит к добавлению к коду команды префикса замены сегментного регистра, так как все команды с обращением к памяти по умолчанию используют для адресации именно регистр DS.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]