MS-DOS за програмист
5. Резидентни програми
В тази глава ще ви разкажем как да създавате резидентни програми. Такива програми се наричат още TSR програми (прекратяване и оставане постоянно).
Какво е резидентска програма?
Обикновено, след завършване на следващата програма, MS-DOS освобождава паметта, която е заела програмата, за да зареди нова на това място. Има обаче начин да оставите програмата в паметта, след като приключи. Такава програма ще бъде резидентна, т.е. постоянно присъстваща в паметта.
За какво се използват програмите за пребиваване?
Резидентните програми могат да поемат обработката на прекъсвания, например тези, свързани с печат или достъп до клавиатурата и т.н.
Друг пример за използване на резидентни програми са резидентни калкулатори, референтни бази данни или интегрирани системи като SideKick на Borland.
Такива програми също обикновено се стартират чрез файла autoexec.bat или при необходимост. Те прихващат прекъсвания, предназначени за работа с клавиатурата. Веднага щом потребителят натисне предварително дефинирана клавишна комбинация, резидентната програма се активира. Върху изображението на екрана се показва диалогов прозорец на резидентната програма.
Понякога се използват резидентни програми вместо драйвери за изтегляне за обслужване на нестандартен хардуер. В този случай резидентната програма може да вгради свой собствен манипулатор, чрез който всички приложни програми имат достъп до хардуера.
Резидентните модули на някои системи за управление на бази данни (СУБД) работят по подобен начин. Приложната програма изпраща заявки към базата данни чрез прекъсване, което се задава при стартиране на такава СУБД.
Повече да обслужваме нестандартно оборудванеподходящи са драйвери за изтегляне, които ще обсъдим по-подробно в следващата глава. Драйверите предоставят много по-гъвкави и богати средства за комуникация с устройства, отколкото резидентните програми. Въпреки това, ако просто трябва да обработите няколко прекъсвания или да създадете контролна програма за някое просто устройство, тогава резидентните програми са това, от което се нуждаете.
Вероятно сте чували, че не е лесно да напишете добре работеща резидентна програма. Ние сме напълно съгласни с това. Има много причини, основната е, че Microsoft не предостави на програмистите цялата необходима информация за това.
На резидентните програми се налагат множество ограничения, които затрудняват работата на програмиста.
Например, на TSR не е позволено да използват MS-DOS прекъсвания по желание. Това е така, защото MS-DOS е проектирана от самото начало като еднозадачна операционна система, така че функциите за прекъсване на MS-DOS не се въвеждат повторно.
Представете си такава ситуация.
Да предположим, че нормална програма, наречена някаква функция за прекъсване на MS-DOS, отнема сравнително дълго време, за да завърши (например запис на диск).
Тъй като потребителят може да активира резидентна програма по всяко време, ако не са взети специални предпазни мерки, е възможно да извика отново същата функция, чиято обработка все още не е завършена. В този случай ще получим обратно извикване на функцията на MS-DOS, което е невалидно поради факта, че функциите на MS-DOS не се въвеждат повторно.
Без да се вземат специални предпазни мерки, резидентната програма не може да извика много функции на библиотеката на преводача, тъй като последното извикванеMS-DOS прекъсва. Например функцията malloc предизвиква прекъсване на MS-DOS, за да определи количеството свободна памет в системата.
Трудности могат да възникнат и при използването на аритметика с плаваща запетая. Това е така, защото функцията _dos_keep възстановява прекъсванията, използвани за емулиране на аритметика с плаваща запетая и за работа с аритметичния копроцесор.
Как да запазите резидентна програма в паметта?
Програмата има две опции да остане резидентна в паметта - използвайте прекъсването INT 27h или функцията за прекъсване INT 21h 31h.
За да използвате прекъсването INT 27h, сегментният регистър на CS трябва да сочи към PSP на програмата. В този случай отместването на последния байт на програмата плюс един байт трябва да бъде записано в DX регистъра.
Лесно е да се види, че този метод е най-подходящ за com-програми, тъй като с помощта на прекъсването INT 27h е невъзможно да се остави резидентна програма, по-дълга от 64 KB в паметта.
Друг, по-удобен начин е да извикате функцията за прекъсване 31h INT 21h. В регистъра AL можете да посочите кода за прекратяване на програмата, регистърът DX трябва да съдържа дължината на резидентната част на програмата в параграфи. Вече няма горното ограничение за размера на програмата.
За да запазите програма, по-голяма от 64 KB, резидентна в паметта, можете да използвате само последния метод. Но не се увличайте с големи резидентни програми, тъй като паметта, която те заемат, е необходима на други програми.
Библиотеката от функции на системата за разработка Borland C++ съдържа специална функция, предназначена да поддържа програмата резидентна в паметта.
Тази функция използва прекъсването INT 21h (функция 31h) и се нарича _dos_keep.Първият параметър на функцията е изходният код (това, което се записва в AL регистъра), а вторият е размерът на резидентната част на програмата в параграфи.
Трябва внимателно да следите размера на останалата резидентна част от програмата. Ако зададете грешен размер за функцията _dos_keep, тогава резидентната програма може да бъде унищожена от програмата, заредена след нея. Всичко това в крайна сметка ще доведе до разрушаване на операционната система и необходимостта от рестартиране.