MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 18, М.: Диалог-МИФИ, 1995, 254 стр. 5. Резидентные программы
В этой главе мы расскажем вам о том, как создавать резидентные программы . Такие программы еще называют TSR-программами (Terminate and Stay Resident ). Что это такое резидентная программа? Обычно после завершения очередной программы MS-DOS освобождает место в памяти, которое занимала программа, чтобы загрузить на это место новую. Однако есть способ оставить программу в памяти и после ее завершения. Такая программа и будет резидентной, т. е. постоянно присутствующей в памяти. Для чего используются резидентные программы ? Резидентные программы могут переключать на себя обработку прерываний, например, связанных с выводом на печать или с обращением к клавиатуре и т. д. Вы можете встретить множество резидентных программ, предназначенных для загрузки русских шрифтов в память видеоконтроллера , для печати текста, содержащего символы кириллицы, на принтере в графическом режиме, для русификации клавиатуры и т. п. Все эти программы обычно запускаются один раз при загрузке компьютера через файл autoexec.bat . Другой пример использования резидентных программ: резидентные калькуляторы, справочные базы данных или интегрированные системы, наподобие Borland SideKick. Такие программы тоже обычно запускаются через файл autoexec.bat или при необходимости. Они перехватывают прерывания, предназначенные для работы с клавиатурой. Как только пользователь нажимает заранее определенную комбинацию клавиш, резидентная программа активизируется. Поверх имеющегося на экране изображения выводится диалоговое окно резидентной программы. Иногда резидентные программы используют вместо загружаемых драйверов для обслуживания нестандартной аппаратуры. В этом случае резидентная программа может встроить свой обработчик, через который все прикладные программы смогут обращаются к аппаратуре. Аналогично работают резидентные модули некоторых систем управления базами данных (СУБД). Прикладная программа посылает запросы к базе данных через прерывание, устанавливаемое при запуске такой СУБД. Для обслуживания нестандартной аппаратуры больше подходят загружаемые драйверы, о которых мы еще будем подробно говорить в следующей главе. Драйверы предоставляют намного более гибкие и богатые средства общения с устройствами, чем резидентные программы . Однако если вам требуется всего лишь обработать несколько прерываний или создать программу управления каким-нибудь несложным устройством, то резидентные программы - это то, что вам нужно. Вы, наверное, слышали, что составить правильно работающую резидентную программу не так просто. Мы полностью с этим согласны. Причин много, главная заключается в том, что фирма Microsoft не предоставила в распоряжение программистов всю необходимую для этого информацию. На резидентные программы накладываются многочисленные ограничения, затрудняющие работу программиста. Например, резидентным программам не разрешается использовать прерывания MS-DOS, когда вздумается. Это связано с тем, что MS-DOS с самого начала проектировалась как однозадачная операционная система, поэтому функции прерываний MS-DOS не обладают свойством реентерабельности (повторной входимости). Представьте себе такую ситуацию. Пусть обычная программа вызвала какую-либо функцию прерывания MS-DOS, на выполнение которой требуется относительно много времени (например, запись на диск). Так как пользователь может активизировать резидентную программу в любой момент, то если не принять специальных мер предосторожности, возможен повторный вызов той же самой функции, обработка которой еще не завершена. В этом случае мы получим повторный вызов функции MS-DOS, который недопустим из-за того, что функции MS-DOS не реентерабельны. Функции BIOS также далеко не все реентерабельны. Резидентная программа может смело вызывать разве лишь прерывание INT 16h (которое предназначено для работы с клавиатурой). Если резидентной программе нужно вывести что-нибудь на экран, то вместо прерывания INT 10h следует выполнить непосредственную запись символов и их атрибутов в видеопамять. Без принятия специальных мер предосторожности резидентная программа не может вызывать многие функции библиотеки транслятора, так как последние вызывают прерывания 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 неправильный размер, то резидентная программа может оказаться разрушенной программой, загруженной следом за ней. Все это, в конечном счете, приведет к разрушению операционной системы и к необходимости ее перезапуска. |