Цель работы: изучение структуры и принципов программирования резидентных программ на языке Ассемблер.
Задача: Разработать программу-резидент которая при запуске остается в памяти, перехватывает прерывания часов и клавиатуры. Программу также должна занимать в памяти 1 кб и проверять наличие себя в памяти. Запуск и проверка должна осуществляться с использованием ключей в командной строке.
Эта программа-резидент занимает в памяти объем 1 кб т.к. она избавляется от переменных ипользуя функцию 21-ого прерывания 49h. При запуске программы можно васпользоваться ключями:
/i - загрузить в резидент в память
/p – проверить наличие программы впамяти
Во время запуска программа сохраняет старые прерывания часов и клавиатуры и подставляет свои. При нажатии на клавишу ScrollLock в левом верхнем углу появляются часы, которые отсчитывают текущее системное время. При повторном нажатии часы исчезают. При нажатии на клавишу Esc резидент выгружается из памяти.
В начале резидентного модуля я написал строку QWERTY. С помощью этой метки ведется поблочная проверка памяти на присутствие этой строки. Если в начале какого-то блока эта строка присутствует, значит программа загружена в память.
386DX(SX) процессор и выше
MS-DOS или Windows
6,02 кб на жестком диске
1 Мб оперативной памяти
.286c
.Model tiny
Locals
Jumps
.Code
_nu label near
;------------------------Прога резидент------------------------.Startup
jmp Start
label1 db 'QWERTY'
label2:
ESC_KEY equ 1
SCROLL_LOCK_KEY equ 70
Old09 dd ?
Old08 dd ?
Visible db 0
ScrText dw 8 dup(?)
TimeText dw 2000h,2000h,203Ah,2000h,2000h,203Ah,2000h,2000h
ExitMsg db 'Программа "ЧАСЫ" убилась',13,10,'$'
int_09 proc far
push ax ;Размещает содержимое AX в стеке
in al,60h ;скан-код
cmp al,ESC_KEY ;Выход?
jne int09_test_F11 ;Если нет goto
call Upload
push es ;********************
mov ax,cs ;********************
mov es,ax ;********************
mov ah,49h ;********************
int 21h ;********************
pop es ;********************
pop ax ;Восстановление
jmp dword ptr cs:[Old09]
int09_test_F11:
cmp al,SCROLL_LOCK_KEY ;Вкл/выкл?
jne int09_exit ;Если нет goto
call Swap_visibility
int09_exit:
pop ax ;Восстановление
jmp dword ptr cs:[Old09]
;--------------------------------------------------------------Int_08:
cmp cs:[Visible],1
jne int08_exit
call Show_timer
int08_exit:
jmp dword ptr cs:[Old08]; Передача упр.на старое прерывание
;----------------------Видно/невидно---------------------------Swap_visibility PROC NEAR
pusha
push ds
push es
cld
cmp cs:[Visible],1
je Sw_vis_Hide
Sw_vis_show:
mov ax,0B800h
mov ds,ax
xor si,si
mov ax,cs
mov es,ax
mov di,offset ScrText
mov cx,8
rep movsw
mov cs:[Visible],1
call Show_timer
jmp Sw_vis_exit
Sw_vis_hide:
mov ax,0B800h
mov es,ax
xor di,di
mov ax,cs
mov ds,ax
mov si,offset ScrText
mov cx,8
rep movsw
mov cs:[Visible],0
Sw_vis_exit:
pop es
pop ds
popa
ret
Swap_visibility ENDP
;-----------------------Изображение таймера--------------------Show_timer PROC NEAR
pusha ;Сунуть регистры встек
push ds ;Размещает DS
push es ;Размещает ES
mov ax,0B800h
mov es,ax
mov ax,cs
mov ds,ax
mov ah,2
int 1Ah
mov bx,offset TimeText+14
mov al,dh
and al,0Fh
or al,30h
mov [bx],al
sub bx,2
mov al,dh
shr al,4
or al,30h
mov [bx],al
sub bx,4
mov al,cl
and al,0Fh
or al,30h
mov [bx],al
sub bx,2
mov al,cl
shr al,4
or al,30h
mov [bx],al
sub bx,4
mov al,ch
and al,0Fh
or al,30h
mov [bx],al
sub bx,2
mov al,ch
shr al,4
or al,30h
mov [bx],al
xor di,di
mov si,offset TimeText
mov cx,8
rep movsw
pop es
pop ds
popa
ret
Show_timer ENDP
;---------------------Выгрузка резидента------------------------Upload PROC NEAR
push ds
push ax
push dx
mov ax,2509h
lds dx,dword ptr cs:[Old09]
int 21h
mov ax,2508h
lds dx,dword ptr cs:[Old08]
int 21h
cmp cs:[Visible],1
jne Dont_hide_at_upload
call Swap_visibility
Dont_hide_at_upload:
mov ax,cs
mov ds,ax
mov ah,09
mov dx,offset ExitMsg
int 21h
pop dx
pop ax
pop ds
ret
Upload ENDP
int_09 endp
Lastbyte:
;-----------------------Загрузка резидента----------------------Start:
mov ah,09
mov dx,offset InstMsg
int 21h
;------------------Comand line----------------------;
mov si,80h
lodsb
cmp al,13
jz OutLine
ww1:
lodsb
cmp al,20h ;лишние пробелы
loopz ww1
stosb
cmp al,'/'
jz checkOption
cmp al,'-'
jz checkOption
jmp OutLine
checkOption:
lodsb
and al,0ffh-20h ;map to upper case
cmp al,'P'
jnz CheckI
jmp Prov
CheckI:
cmp al,'I'
jnz OutLine
jmp InstRes
OutLine:
mov ah,09
mov dx,offset ComLine
int 21h
jmp ExtProg
;---------------Проверка на наличие в памяти----;
Prov:
mov ah,52h
int 21h
mov es,es:[bx-2]
mov si,offset Label1
mov cx,offset Label2-Label1
cld
qq1:
cmp word ptr es:[0001h],0h
je qq3
push si
push cx
lea di,[si+10h]
repz cmpsb
pop cx
pop si
je qq2
qq3:
mov ax,es
add ax,es:[0003h]
inc ax
mov es,ax
cmp byte ptr es:[0000],'M'
je qq1
mov ah,09
mov dx,offset NoPresMsg
int 21h
jmp ExtProg
;-----------Установка новых прерываний -----------;
InstRes:
mov ax,3509h ;Сохранение старых прерываний
int 21h
mov word ptr Old09,bx
mov word ptr Old09+2,es
mov ax,3508h
int 21h
mov word ptr Old08,bx
mov word ptr Old08+2,es
mov ax,2509h ;Установка нового вектора прерываний
mov dx,offset Int_09
int 21h
mov ax,2508h
mov dx,offset Int_08
int 21h
mov ah,09
mov dx,offset HotKey
int 21h
cmp ax,ax
je ExtProg
qq2:
mov ah,09
mov dx,offset PresMsg
int 21h
ExtProg:
mov dx,offset Start
int 27h
InstMsg db ' Resident "ЧАСЫ" beta version ',13,10
db ' Created by Шипилов С.В.',13,10,'$'
HotKey db ' Scroll Lock - Показать/спрятать часы',13,10
db ' Esc - Выгрузка резидента',13,10,'$'
ComLine db ' /i - Load to memory',13,10
db ' /p - Check instalation',13,10,'$'
PresMsg db ' Я УЖЕ ЗДЕСЬ!!!',13,10,'$'
NoPresMsg db ' МЕНЯ В ПАМЯТИ НЕТ!!!',13,10,'$'
;--------------------------------------------------------------mov ax,4cffh
int 21h
end
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.