Ассемблер (assembler). Разработка резидентых обработчиков
Рефераты >> Программирование и компьютеры >> Ассемблер (assembler). Разработка резидентых обработчиков

Выгрузка резидента происходит следующим образом: в командной строке прописывается имя файла «пробел» off, после этого будет выведено сообщение об выгрузке резидента из памяти.

4. Листинг программ

Файл RES.asm

;Студент: Шевченко Н.С. преподаватель: Афанасьев В.А.

;Вариант 11

;Задание: Реализовать Резидент-замедлитель исполнения программ.

;Замедление реализуется поцедурой задержки, вставленной

; в обработчик прерывания пользователя по таймеру (int 1Ch).

;Инициализация резидента осуществляется через

;посредство комбинации клавиш <Scroll Lock+Цифровая клавиша>.

;Значение символа цифровой клавиши влияет на скорость замедления

;Res.com - основнной модуль, содержащий резидент с пользовательскими

;обработчиками new_1Ch, new_09h и new_2Fh заменяющими соостветствующие

;обработчики 1Ch, 09h и 2Fh

;test.exe - демонстрационная программа, показывающая на примере

;вывода системного времени работу резидента

IDEAL

MODEL TINY

p486n

CODESEG

org 100h ;Установим IP на адрес после PSP

MACRO cprintf mes,len,attrib,x,y,n

mov ah,13h

mov al,1 ;Признак смещения курсора в конец строки

mov bh,n ;Номер видеостраницы

mov bl,attrib

mov cx,len

mov dh,y

mov dl,x

mov bp,offset mes ;Адрес строки ES:BP

int 10h

ENDM cprintf

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

Proc resident

jmp init ; Переход на секцию инициализации

old_1Ch dd 0 ; Адреса заменяемых обработчиков

old_2Fh dd 0 ;

old_09h dd 0 ;

ten db 10 ; Основание сисемы исчисления

fn db 0 ; Режим работы резидента

Proc new_1Ch ; Пользовательский обработчик new_1Ch

pusha

push ds es

mov ax,cs

mov ds,ax ;ds=cs

cmp [cs:cnt],0 ; время замедления равно 0

je end_out ; то идём на выход

mov cx,[cs:cnt] ;Число внешних циклов

outer: push cx ;собственно задержка

mov cx,0 ;

;

inner: loop inner ;0FFFFh - число внутренних циклов

pop cx ;

loop outer ;

mov ah,02h ; иначе выведем на экран

int 1Ah ; в определённые координаты (для демонстрации)

; строку системного время с атрибутом

; показать замедленное время

mov al,ch

call bin_asc ; вызовем функцию перевода в ASCII символы

mov [cs:clock],ah ; сохраним значения

mov [cs:clock+2],al ;

mov al,cl

call bin_asc

mov [cs:clock+6],ah

mov [cs:clock+8],al

mov al,dh

call bin_asc

mov [cs:clock+12],ah

mov [cs:clock+14],al

mov cx,clock_len

mov ax,0B800h

mov es,ax

mov di,[cs:locate]

mov si,offset clock ; выведем строку на экран

cld

rep movsb

end_out:

pop es ds ; восстановим все регистры

popa

jmp [dword cs:old_1Ch]

iret

; выйдем из процедуры

Endp new_1Ch

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

Proc bin_asc ; Процедура преобразования BCD-кода

;mov ah, al

;sub ah, al

;shr ah, 1

;sub al, 10

;add ah, '0'

;add al, '0'

mov ah,al ; из регистра al в ASCII-символы

and al,0Fh

shr ah,4

or ax,3030h

ret

Endp bin_asc

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

clock DB 2 DUP(20h,1Fh),":",1Fh ; строка системного времени с атрибутом

DB 2 DUP(20h,1Fh),":",1Fh,2 DUP(20h,1Fh)

clock_len = $-clock ; длинна строки

locate DW 1352 ; 1352 позиция точки ввода на экране

cnt DW 0 ; коэффициент замедления

f1 DB 0 ; 0- не производить замедление 1- наоборот

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

Proc new_09h ; пользовательский обработчик new_09h

pusha ; Сохраним регистры

push es

push ds

in al,60h ; Введём скан-код

cmp al,0Bh

je h0

cmp al,02h

je h1

cmp al,03h

je h2

cmp al,04h

je h3

cmp al,05h

je h4

cmp al,06h

je h5

cmp al,07h

je h6

cmp al,08h

je h7

cmp al,09h

je h8

xxx:

pop ds ; Если ни одна из комбинаций клавиш не

pop es ; присутствует, то восстановим регистры

popa ; и в системный обработчик без вовзврата

jmp [dword cs:old_09h]

h0: mov ax,40h ;Настроим ES на сегмент данных BIOS

mov es,ax

mov al,[es:17h] ;Получим первый байт флагов

and al,00010000b ;выделяем 4-ый бит

cmp al,0 ;Клавиша Scroll Loсk нажата?

je xxx

;test al,10h ;Клавиша Scroll Loсk нажата?

;je xxx ;если нет, то выйдем

mov [cs:fn],0h ; если гажата, то выставим соответствующий режим

mov [cs:cnt], 0

jmp xxxx ; работы резидента, и пойдём на выход

h1: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],1h

mov [cs:cnt], 0

jmp xxxx

h2: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],2h

mov [cs:cnt],160

jmp xxxx

h3: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],3h

mov [cs:cnt], 240

jmp xxxx

h4: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],4h

mov [cs:cnt],320

jmp xxxx

h5: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],5h

mov [cs:cnt],400

jmp xxxx

h6: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],6h

mov [cs:cnt], 480

jmp xxxx

h7: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],7h

mov [cs:cnt],560

jmp xxxx

h8: mov ax,40h

mov es,ax

mov al,[es:17h]

test al,10h

je xxx

mov [cs:fn],8h

mov [cs:cnt],640

jmp xxxx

xxxx: in al,61h ;Введём содержимое порта 61h

or al,80h ;Подтвердим приём кода, записав 1 в старший

out 61h,al ;бит порта 61h

and al,7Fh ;Снова разрешим работу контроллера клавиатуры

out 61h,al ;сбросив старший бит порта 61h

mov al,20h ;20h - команда EOI

out 20h,al ;20h - порт контроллера

pop ds ;Восстановим регистры

pop es

popa

iret ; выйдем из прерывания

Endp new_09h

Proc new_2Fh ; мультиплексное прерывание

cmp ah,0C7h ; Если поступил запрос на режим работы резидента

jne dalshe ; то вернём его в младшем байте регистра ax

mov al,[cs:fn] ; иначе продолжим .

iret ;

dalshe:

cmp ah,0C8h ; Наша функция?

jne out_2Fh ; Не наша, - на выход

cmp al,00h ; Подфункция проверки на повторную установку

je i_here ; Да, сообщим о невозможности повторной установки

cmp al,01h ; Подфункция выгрузки?

je uninst ; Да, на выгрузку

jmp short out_2Fh ; Неизвестная подфункция, на выход

i_here: mov al,0ffh

iret

out_2Fh:jmp [dword cs:old_2Fh] ; Переход в следующий по цепочке обработчик

uninst: push ds

push es

push dx

mov ax,251Ch ; Восстановим вектор 1Ch

lds dx,[cs:old_1Ch]

int 21h


Страница: