Способ создания TSR программ без PSPDelphi , Программа и Интерфейс , Приложение своёСпособ создания TSR программ без PSP
Оформил: DeeCo Несколько слов о TSR. При разработке TSR - программ стандартными средствами DOS в памяти после завершения программы остается PSP размером 256 байт или по крайней мере его часть, если программа использует область FCB (File Control Block) и параметров для собственных нужд. Мы расскажем Вам о способе, позволяющем полностью использовать область PSP в интересах резидентной программы и приведем пример такой программы. Данный способ был разработан авторами в начале 1989 года, когда потребовалось загрузить много крохотных TSR - программ, размер которых не превышал PSP. Кое-что о недокументированных функциях DOS. Для понимания механизма разработки TSR без PSP необходимо ознакомиться с некоторыми недокументированными функциями DOS и с форматами PSP и MCB - Memory Control Block. PSP - program segment prefix. PSP всегда строится DOS при запуске любой программы и непосредственно предшествует началу программы. Рассмотрим формат PSP.
MCB - memory control block. MCB является блоком DOS описывающим каждый распределенный участок памяти. Как правило MCB всегда строится перед PSP исполняемой программы. Рассмотрим формат MCB.
Недокументированные функции DOS. Рассмотрим теперь недокументированные функции DOS, которые используются для построения TSR без PSP. установить текущий PSP. Данная функция указывает DOS, что в качестве текущего следует использовать указанный PSP. Входные параметры: AH = 50h BX = сегментный адрес нового PSP. создать подчиненный PSP. Данная функция требует от DOS создать подчиненный PSP. В отличии от функции 26h данные не копируются из текущего PSP, а строятся заново. Входные параметры: AH = 55h BX = сегментный адрес для построения нового PSP. SI = значение, которое требуется установить в поле со смещением 2 в новом PSP. Процесс завершения резидентной программы. Сущность завершения резидентной программы без PSP состоит в создании нового PSP и указании DOS использовать этот PSP в качестве активного. При этом сам текст резидентной части перемещается на начало старого PSP. Рассмотрим последовательность действий при завершении программы. Освободить ENVIRONMENT, адрес которого находится в PSP по смещению 2Ch. Вообще говоря, это действие не связано с собственно процессом завершения резидентной программы без PSP и рекомендуется для любого способа завершения резидентных программ. Изменить размер памяти, используемый программой, указав в качестве нового размера длину резидентной части программы в параграфах, а в качестве адреса модифицируемой памяти - сегментный адрес PSP. Для выполнения используется функция DOS 4Ah. Если резидентная часть начинается с начала программы, то ее следует сначала сохранить, т.к. при освобождении памяти в теле программы будет построен новый MCB. Также целесообразно зарезервировать после резидентной части участок длиной 16 байт для MCB, чтобы последующие действия не уничтожили дальнейший код программы. Вычисляется сегментный адрес для построения нового PSP по формуле <длина резидентной части в параграфах>+<сегментный адрес старого PSP>+1 (размер MCB в параграфах). Строится новый PSP по вычисленному сегментному адресу с использованием функции 55h. В качестве значения SI берется поле со смещением 2 в старом PSP. Корректируется адрес родительского PSP в новом PSP по смещению 16h. Значение выбирается из поля с таким же смещением из старого PSP. Новый PSP указывается DOS в качестве текущего с использованием функции 50h. Корректируется указатель на собственника памяти в новом MCB по смещению 01h. MCB расположен по сегментному адресу равному сегменту нового PSP минус 1. Значение указателя устанавливается равным сегментному адресу нового PSP. Резидентная часть программы пересылается по адресу сегмента старого PSP со смещением 0. Выполняются необходимые действия для настройки резидентной части. Их можно также выполнить заранее. Программа завершается обычным образом по функции DOS 04Ch. Совместимость. Данный метод опробован в различных совместимых операционных средах: - MS/PC DOS 3.30; - MS/PC DOS 4; - MS DOS 5 beta release; - DR DOS 3.41; - DR DOS 5; - с использованием загрузчика LOADHI от системы QEMM 5.0; - с использованием загрузки в старшую память HILOAD DR DOS 5. Пример резидентной программы без PSP. Для лучшего понимания порядка завершения резидентной программы без PSP приведем пример. page 60, 132 title NONPSP - Резидентная программа без PSP ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ; Пример построения резидентной программы без PSP ; ; Авторские права ГРУППЫ ПРОГРАММИСТОВ 2 B ; ; Язык программирования: Ассемблер ; Транслятор: MASM ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ; сообщить транслятору адресацию ; assume cs: code, ds: code, es: nothing ; ; определить сегмент кода ; code segment para ; subttl Резидентная часть программы ; ResStart label byte; определим начало программы ; Текст резидентной части. ResEnd label byte; конец резидентной части ResLen equ ResEnd - ResStart; размер резидентной части в ; байтах ResSize equ(ResEnd - ResStart + 15) / 16; размер резидентной ; части в параграфах org ResStart + ResSize * 16; для выравнивания на ; границу параграфа ; page subttl Инициализация резидентной программы без PSP ; MCBLen equ 10 h; размер MCB ; PSPMCB db MCBlen dup(0); резервная область для MCB SavRes db ResLen dup(0); область сохранения ; резидентной части ; PspOld dw 0; для адреса старого PSP PspNew dw 0; для адреса нового PSP ; ; сообщения ; MsgInst label byte db 0 ah, 0 dh db 'Программа установлена' db 0 ah, 0 dh db '$' MsgNoInst label byte db 0 ah, 0 dh db 'Ошибка. Программа не установлена' db 0 ah, 0 dh db '$' ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; ; процедура инициализации резидентной программы без PSP ; ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ini proc far ; cld; для операций пересылки mov cs: PspOld, ds; сохраним старый PSP ; ; Освобождение environment ; mov ax, ds: [2 ch]; адрес сегмента mov es, ax; environment cmp ax, 0; есть environment ? je Go1; нет mov ah, 49 h; код функции int 21 h; освободить ; память jnc Go1; успешно jmp ErrorRet; неуспешно Go1: mov word ptr ds: [2 ch], 0; укажем, что нет ; environment push cs; установим pop es; ES push cs; установим pop ds; DS ; ; запомним резидентную часть ; т.к.она будет разрушена при построении новых PSP и MCB ; mov si, Offset ResStart; откуда mov di, Offset SavRes; куда mov cx, ResLen; сколько rep movsb; перешлем ; ; модифицируем размер памяти текущей программы от сегмента ; PSP на длину резидентной части ; это приведет к построению нового MCB в теле программы ; mov ah, 4 ah; модифицируем память mov bx, ResSize; размер резидентной ; части mov es, PspOld; сегмент старого PSP int 21 h; выполним jnc Go2; успешно jmp ErrorRet; неуспешно Go2: ; ; подсчитаем сегмент памяти для нового PSP ; mov ax, ResSize; длина резидентной ; части в параграфах add ax, PspOld; плюс сегмент ; старого PSP add ax, MCBLen / 16; плюс длина MCB mov PspNew, ax; запомним сегмент ; для нового PSP ; ; создадим новый PSP ; mov es, PspOld; адрес старого PSP mov si, word ptr es: [02 h]; конец памяти mov ah, 55 h; построим ; подчиненный PSP mov dx, PspNew; сегмент нового PSP int 21 h; выполним ; ; скорректируем указатель на родительский PSP в новом PSP ; mov es, PspOld; сегмент старого PSP mov ax, word ptr es: [16 h]; адрес родительского ; PSP mov es, PspNew; сегмент нового PSP mov word ptr es: [16 h], ax; скорректируем ; ; сообщим DOS о новом активном PSP ; mov bx, PspNew; сегмент нового PSP mov ah, 50 h; функция указания нового PSP int 21 h; выполним ; ; укажем принадлежность полученной памяти для нового PSP ; mov ax, bx; сегмент нового PSP sub ax, 1; сегмент ; построенного MCB mov es, ax ; = = = = = = = = = = = = = = = = = = mov word ptr es: [01 h], bx; скорректируем адрес ; владельца памяти ; ; переместим резидентную часть на старый PSP ; mov es, PspOld; адрес старого PSP mov cx, ResLen; размер резидентной ; части mov di, 0; куда mov si, Offset SavRes; откуда rep movsb; переместим push cs; восстановим pop es; ES ; ; Успешный выход из программы ; PrgEnd: mov ah, 09 h; выведем сообщение mov dx, offset MsgInst; об успешной ; установке int 21 h; mov ax, 4 c00h; завершим программу int 21 h; обычным ; образом с кодом 0 ; ; Выход из программы по ошибке ; ErrorRet: push cs; установим адресацию pop ds; данных mov ah, 09 h; выведем сообщение mov dx, offset MsgNoInst; о неуспешной ; установке int 21 h; mov ax, 4 c04h; завершим программу int 21 h; обычным ; образом с кодом 4 ini endp ; code ends ; ; СТЕК ; stack segment stack dw 512 dup(0) stack ends end ini Способ создания резидентных программ без PSP позволяет использовать область PSP для размещения резидентного кода программы, обеспечивая тем самым полноценную работу программы в памяти. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: Приложение своё ::
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |