MS-DOS для програміста
5. Резидентні програми
У цьому розділі ми розповімо вам про те, як створювати резидентні програми. Такі програми ще називають TSR-програмами (Terminate and Stay Resident).
Що таке резидентна програма?
Зазвичай після завершення чергової програми MS-DOS звільняє місце у пам'яті, яке займала програма, щоб завантажити нове. Однак є спосіб залишити програму в пам'яті та після її завершення. Така програма і буде резидентною, тобто постійно присутньою у пам'яті.
Для чого використовуються резидентні програми?
Резидентні програми можуть перемикати на себе обробку переривань, наприклад, пов'язаних з виведенням на друк або зверненням до клавіатури і т.д.
Інший приклад використання резидентних програм: резидентні калькулятори, довідкові бази даних або інтегровані системи, на зразок Borland SideKick.
Такі програми теж зазвичай запускаються через файл autoexec.bat або за потреби. Вони перехоплюють переривання, призначені до роботи з клавіатурою. Як тільки користувач натискає певну комбінацію клавіш, резидентна програма активізується. Поверх наявного зображення відображається діалогове вікно резидентної програми.
Іноді резидентні програми використовують замість драйверів, що завантажуються, для обслуговування нестандартної апаратури. У цьому випадку резидентна програма може вбудувати свій оброблювач, через який усі прикладні програми зможуть звертатися до апаратури.
Аналогічно працюють резидентні модулі деяких систем керування базами даних (СУБД). Прикладна програма надсилає запити до бази даних через переривання, яке встановлюється під час запуску такої СУБД.
Для обслуговування нестандартної апаратури більшепідходять драйвери, що завантажуються, про які ми ще будемо докладно говорити в наступному розділі. Драйвери надають набагато більш гнучкі та багаті засоби спілкування з пристроями, ніж резидентні програми. Однак якщо вам потрібно лише обробити кілька переривань або створити програму управління яким-небудь нескладним пристроєм, то резидентні програми - це те, що вам потрібно.
Ви, напевно, чули, що скласти резидентну програму, що правильно працює, не так просто. Ми цілком із цим згодні. Причин багато, головна у тому, що фірма Microsoft не надала у розпорядження програмістів всю необхідну інформацію.
На резидентні програми накладаються численні обмеження, які ускладнюють роботу програміста.
Наприклад, резидентним програмам не дозволяється використовувати переривання MS-DOS, коли заманеться. Це з тим, що MS-DOS від початку проектувалася як однозадачна операційна система, тому функції переривань MS-DOS не мають властивістю реентерабельності (повторної вхідності).
Уявіть собі таку ситуацію.
Нехай звичайна програма викликала будь-яку функцію переривання MS-DOS, на виконання якої потрібно багато часу (наприклад, запис на диск).
Так як користувач може активізувати резидентну програму в будь-який момент, то якщо не вжити спеціальних запобіжних заходів, можливий повторний виклик тієї ж функції, обробка якої ще не завершена. У цьому випадку ми отримаємо повторний виклик функції MS-DOS, який неприпустимий через те, що функції MS-DOS не реентерабельні.
Без вживання спеціальних запобіжних заходів резидентна програма не може викликати багато функцій бібліотеки транслятора, оскільки останні викликаютьпереривання MS-DOS. Наприклад, функція malloc викликає переривання MS-DOS визначення розміру вільної пам'яті у системі.
Можуть виникнути труднощі з використанням арифметичних дій з числами у форматі плаваючої коми. Це відбувається тому, що функція _dos_keep відновлює переривання, що використовувалися для емуляції арифметики з плаваючою комою та для роботи з арифметичним співпроцесором.
Як залишити програму резидентною у пам'яті?
У програми є дві можливості залишитися резидентною в пам'яті – використовувати переривання INT 27h або функцію 31h переривання INT 21h.
Для використання переривання INT 27h сегментний регістр CS повинен вказувати на програму PSP. При цьому в регістр DX слід записати усунення останнього байта програми плюс один байт.
Неважко помітити, що цей спосіб найбільше підходить для com-програм, тому що за допомогою переривання INT 27h неможливо залишити в пам'яті резидентну програму довшу за 64 Кбайт.
Інший, більш зручний спосіб полягає в виклику функції 31h переривання INT 21h . У регістрі AL можна вказати код завершення програми, регістр DX повинен містити довжину резидентної частини програми в параграфах. Тут вже немає зазначеного вище обмеження розміру програми.
Для того, щоб залишити резидентною в пам'яті програму, розмір якої перевищує 64 Кбайт, ви можете використовувати лише останній метод. Але не варто захоплюватися великими резидентними програмами, оскільки пам'ять, яку вони займають, потрібна іншим програмам.
Бібліотека функцій системи розробки Borland C++ містить у своєму складі спеціальну функцію, призначену для залишення резидентної програми в пам'яті.
Ця функція використовує переривання INT 21h (функція 31h) і називається _dos_keep.Перший параметр функції – код завершення (те, що записується в регістр AL), а другий – розмір резидентної частини програми у параграфах.
Потрібно уважно стежити за розміром резидентної частини програми, що залишається. Якщо вказати функції _dos_keep неправильний розмір, то резидентна програма може бути зруйнованою програмою, завантаженою за нею. Все це, зрештою, призведе до руйнування операційної системи та необхідності її перезапуску.