Ассемблер (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