Міністерство освіти і науки України
Національний університет „Львівська політехніка”
Кафедра електронних
обчислювальних машин
Звіт
про виконання розрахункової роботи
з курсу „ Системне програмування ”
Тема: Резидентні програми у ІBM PC.
Львів – 2004
Мета роботи:
Вивчення принципів побудови та функціонування резидентних програмам.
Короткі теоретичні відомості
Програми, що повинні постійно знаходитись в пам'яті і миттєво реагувати на події, що відбуваються в обчислювальній системі, носять назву резидентних в пам'яті (Terminate but Stay Resident, TSR). Резидентною може бути програма, як .COM, так і .EXE формату, одначе, оскільки резидентна програма повинна бути максимально компактною, найчастіше використовується .COM формат.
Резидентні програми, як правило, складаються з двох частин - ініціалізуючої та робочої (резидентної). В тексті програми резидентна частина розміщується на початку, ініціалізуюча – за нею.
Під час першого виклику програма повністю завантажується в пам'ять і управління передається до секції ініціалізації, яка заповнює або модифікує вектори переивань, настроює програму на конкретні умови роботи і за допомогою переривання DOS INT 21h з функцією 31h завершує програму, залишаючи в пам'яті її резидентну частину. Розмір резидентної частини (в параграфах) передається DOS в регістрі DX. Вказувати при цьому сегментну адресу програми немає необхідності, оскільки він відомий DOS.
Для визначення розміру резидентної секції її можна завершити конструкцією вигляду "res_size equ $ - your_proc", де your_proc - адреса початку програми, а при виклику функції 31h в регістр DX переслати результат обчислення виразу (res_size + 10Fh)/16.
Функція 31h, закріпивши за резидентною програмою необхідну для її функціонування пам'ять, передає управління командному процесору COMMAND.COM і обчислювальна система, таким чином, повертається у вихідний стан. Наявність програми, резидентної в пам’яті, ніяк не відбивається на ході основного обчислювального процесу за виключенням того, що зменшується об’єм доступної йому пам’яті. Одночасно може бути завантажено декілька резидентних програм.
Завдання на розрахункову роботу
Створити резидентну програму, що реалізує вказаний викладачем варіант завдання. Програму оформити у вигляді .COM файлу.
Запустити створену програму та задокументувати результати її виконання.
Скласти звіт про виконану роботу.
Варіант 9.
Організувати вивід на екран повідомлення про наявність резидента в пам’яті як реакцію на натискання комбінації клавіш <Alt>/R при неактивному режимі <Caps Lock> і активному режимі <Num Lock> та <Scroll Lock>. Забезпечити вивантаження резидентної програми при натисканні <Ctrl>/R.
Вміст .asm-файлу
.model tiny
.code
;визначення констант
ALT_R EQU 13h
CTRL_R EQU 12h
ORG 100h
myproc PROC far
jmp init
; дані резидентної частини
old_09h DD 0
old_stack DD 0
mesun DB 'CTRL+R - Resident UNloaded.'
DB 10,13,10,13,10,13,10,13,10,13,10,13,10,13,10,13,10,13
mesunlen EQU $-mesun
mesloaded DB 'Resident program is still in memory.'
mesl1len EQU $-mesloaded
mesld2 DB 'Press CTRL+R to unload it.',10,13
mesl2len EQU $-mesld2
; резидентна секція програми
new_09h:
cli
; виклик старого обробника переривання
pushf
call dword ptr cs:old_09h
;перемикання стеку
mov word ptr cs:old_stack,sp
mov word ptr cs:old_stack+2,ss
mov sp,cs
mov ss,sp
mov sp,offset cs:TOS
push bp
push ax
push bx
push cx
push dx
push ds
push es
mov ax,cs
mov ds,ax
mov ax,40h
mov es,ax
; обробка символа з кільцевого буфера без прямого видобування
mov bx,es:1ah
mov ax,es:[bx]
cmp al,CTRL_R ;;;;;;;;;ctrl+r pressed - uninst
je ctrlr
cmp ah,ALT_R
jne continue
test byte ptr es:17h,01000000b
jnz continue
test byte ptr es:17h,00100000b
jz continue
test byte ptr es:17h,00010000b
jz continue
; скен-код - в заданих межах. Перевірити, чи активовано <Caps Lock>?
;test byte ptr es:17h,01000000b
;jnz continue ; skip if CapsLock is on
;test byte ptr es:17h,01110000b
;jz continue ; skip if NumLock & Scroll Lock are off
; вивід повідомлення про стан резидента
mov ax,cs
mov es,ax
mov ah,13h
mov al,1
mov bx,0042
mov cx,mesl1len
mov dh,16
mov dl,22
mov bp,offset cs:mesloaded
int 10h
mov ax,cs
mov es,ax
mov ah,13h
mov al,1
mov bx,0039
mov cx,mesl2len
mov dh,17
mov dl,32
mov bp,offset cs:mesld2
int 10h
; повернення до перерваної програми
continue:
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
pop bp
; відновлення стеку
mov sp,word ptr cs:old_stack+2
mov ss,sp
mov sp,word ptr cs:old_stack
sti
iret
ctrlr:
; завершити роботу обробника / вивести повідомлення
mov ax,cs
mov es,ax
mov ah,13h
mov al,1
mov bx,0078
mov cx,mesunlen
mov dh,16
mov dl,22
mov bp,offset cs:mesun
int 10h
; відновити вектор без застосування функцій DOS
mov ax,0
mov es,ax
mov ax,word ptr cs:old_09h
mov word ptr es:24h,ax
mov ax,word ptr cs:old_09h+2
mov word ptr es:26h,ax
jmp continue
; область стеку
Stack_Array DW 200 dup(0)
TOS LABEL word
endres EQU $-myproc
; секція ініціалізації
init:
; прочитати та зберегти старий вектор переривання
mov ax,3509h
int 21h
mov word ptr cs:old_09h,bx
mov word ptr cs:old_09h+2,es
; встановити новий вектор
mov ax,cs
mov ds,ax
mov ax,2509h
mov dx,offset cs:new_09h
int 21h
; вивід повідомлення
mov ax,cs
mov ds,ax
mov ah,40h
mov bx,1
mov cx,meslen
mov dx,offset cs:mes
int 21h
; залишити резидентним
mov ax,3100h
mov dx,(endres+10Fh)/16
int 21h
; дані ініціалізуючої частини
mes DB ' Resident loaded into memory !',10,13
DB ' ALT+R - test (not active <Caps Lock> & active <Num Lock>&<Scroll Lock>.)',10,13
DB ' CTRL+R - unload.',10,13
meslen EQU $ - mes
myproc ENDP
END myproc
Результат виконання програми
Запускаємо .COM файл:
Resident loaded into memory !
ALT+R - test (not active <Caps Lock> & active <Num Lock>&<Scroll Lock>.)
CTRL+R - unload.
Встановлюємо Num Lock і Scroll Lock увімкненими, а Caps Lock – вимкненим і натискаємо комбінацію клавіш ALT+R:
Resident program is still in memory.
Press CTRL+R to unload it.
Натискаємо комбінацію клавіш CTRL+R:
CTRL+R - Resident UNloaded.
Висновок: Виконуючи цю розрахункову роботу, я вивчив принципи побудови та функціонування резидентних програмам.