С подключением после системного обработчика 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

С подключением после системного обработчика



Рассмотрим подключение обработчика после системного.

Во многих случаях прикладная обработка выполняется в качестве дополнения к системной. Системная программа BIOS отработки прерывания от клавиатуры преобразует скен-коды в коды ASCII, кроме этого выполняет массу дополнительных операций:

- сходит за указателями КБВ и модифицирует их;

- отслеживает нажатие (Ctrl)/(Break) и выполняет при его вводе специфические действия;

- позволяет вводить в КБВ коды непосредственно в цифровом виде с помощью нажатия (Alt) и цифр на цифровой клавиатуре и т.д.

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

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

Например: (Alt)/(U) - é - уголок (левый верхний уголок) и т.д.

 

CODE_SEG SEGMENT

ASSUME CS:CODE_SEG,DS:code_seg

ORG 100H

START:

JMP BEGIN

 

int_2Fh_vector DD?

old_09h DD?

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

;

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

new_09h proc far

 

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

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

 

push AX

push BX

push ES

 

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

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

 

mov BX,ES:[lCh]; Адрес нового хвоста

dec BX; Сместимся назад к последнему

dec BX; введенному символу

cmp BX,lEh; Хвост не вышел за пределы буфера?

jae go; Нет, значит он был где-то внутри буфера

 

mov BX,3Ch; Хвост после вычитания 2 вышел за пределы буфера,

; сл-но он был в самом начале, а последний введенный

; символ находится в самом конце буфера

go:

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

После системного управления передается в наш обработчик, а сегментный регистр EC настраивается на начало области данных BIOS (физический адрес 400h, сегментный адрес 40h).

Пусть перед вводом данного символа буфер был пуст.

 

 

40h:1Еh      
       
Голова 1Аh Мусор Мусор Хвост 1Сh
       
      40h:ЗСh
Фактически в слове, на которое указывают оба указателя, находится код символа, введенного ранее и уже изъятого программой из буфера

 

Это адрес указателя

а не его

содержимое

 

Очередное нажатие клавиши вызывает нашу программу, а из нее - системный обработчик, который заносит двухбайтовый код нажатой клавиши в хвостовой элемент, перемещая хвостовой указатель на следующее слово буфера:

40h:1Eh      
       
Голова 1Аh Скан ASCII  
    Хвост 16h
       
      40h:ЗСh
На первый взгляд, получить код нажатой клавиши можно либо по адресу в головном указателе, либо вычтя 2 из адреса хвостового указателя. Однако ни то, ни другое неверно.

 

 

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

При этом по мере занесения в буфер новых символов, обработке будет подвергаться все тот же самый старый символ. Следовательно, более надежно определять местонахождение последнего символа в буфере по адресу в хвостовом указателе. Однако не всегда этот адрес будет на 2 больше адреса последнего символа, так как буфер - кольцо. В том случае, когда очередная свободная ячейка буфера находилась в самом его конце, по адресу 40h:3Ch, после занесения туда очередного кода хвостовой указатель переместится в начало буфера, указывая на адрес 1Еh. В программе после вычитания 2 из адреса хвостового элемента, проверяется находится ли полученное значение в пределах буфера. Если оно равно или больше 1Еh, команда jae - выполняет переход на продолжение программы. Если полученное значение меньше 1Еh, то это значит, что хвостовой указатель указывает на самое начало буфера, а занесенный только что в буфер код находится в самом его конце:

 

40h:1Eh     Хвост 16h В этом случае в BХ
        заносится адрес последнего
        символа в явном виде
         
         
Голова Скан ASCII 40h:ЗСh  

 

Затем код нажатой клавиши извлекается из буфера и сравнивается с двухбайтовыми кодами (Alt)/(U) и др. - которые являются расширенными кодами ASCII. Если нажато одно из сочетаний, расш. Код ASCII в буфере заменяется на код ASCII символа псевдографики, без смещения указателя и осуществляется переход на go_out для завершения программы.



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 209; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.58.169 (0.015 с.)