16h СЛОВО сегментный адрес PSP родительского
процесса (адрес текущего PSP для
процесса, у которого нет родителя).
18h 20 БАЙТ FILE HANDLE TABLE. Содержит 20
однобайтовых индексов для системной
таблицы файлов. Первые пять входов
предназначены для STDIN, STDOUT,STDERR,
AUXIO и LSTOUT.
2Ch СЛОВО сегментный адрес блока среды для
процесса.
2Eh ДВ.СЛОВО область сохранения указателя стека
процесса, когда процесс использует стек
DOS (т.е. содержимое SS:SP перед
последним подключением функции DOS с
помощью INT 21h).
32h СЛОВО максимальное количество входов в FILE
HANDLE TABLE (по умолчанию 20).
34h ДВ.СЛОВО адрес FILE HANDLE TABLE (стандартно
указывает на таблицу в текущем PSP).
38h 24 БАЙТА резерв.
50h 3 БАЙТА команда INT 21h, за которой следует
команда far RET. Используется для
вызова диспетчера функций DOS.
53h 2 БАЙТА резерв.
55h 7 БАЙТ расширение первого FCB.
5Ch 16 БАЙТ начальные байты первого неоткрытого
FCB. Открытие данного FCB приведет к
разрушению второго FCB и байта с длиной
командной строки.
6Ch 16 БАЙТ начальные байты второго неоткрытого
FCB. Открытие данного FCB приведет к
разрушению командной строки.
7ch ДВ.СЛОВО резерв.
80h 128 БАЙТ область DTA (Data Transfer Area) по
умолчанию. Перекрывает байт с длиной
командной строки и буфер командной
строки (127 байтов).
Размер блока - 256 байт.
3
MCB - MEMORY CONTROL BLOCK.
MCB является блоком DOS описывающим каждый
распределенный участок памяти. Как правило MCB всегда
строится перед PSP исполняемой программы. Рассмотрим формат
MCB.
СМЕЩЕНИЕ РАЗМЕР ОПИСАНИЕ
00h БАЙТ тип блока:
'M' (4Dh) - промежуточный блок;
'Z' (5Ah) - последний блок.
01h СЛОВО сегмент владельца блока, 0 - свободный
блок.
03h СЛОВО количество параграфов в блоке.
05h 11 БАЙТ резерв.
Размер блока - 16 байт.
НЕДОКУМЕНТИРОВАННЫЕ ФУНКЦИИ DOS.
Рассмотрим теперь недокументированные функции DOS,
которые используются для построения TSR без PSP.
УСТАНОВИТЬ ТЕКУЩИЙ PSP.
Данная функция указывает DOS, что в качестве текущего
следует использовать указанный PSP.
ВХОДНЫЕ ПАРАМЕТРЫ:
AH = 50h
BX = сегментный адрес нового PSP.
СОЗДАТЬ ПОДЧИНЕННЫЙ PSP.
Данная функция требует от DOS создать подчиненный PSP.
В отличии от функции 26h данные не копируются из текущего
PSP, а строятся заново.
ВХОДНЫЕ ПАРАМЕТРЫ:
AH = 55h
BX = сегментный адрес для построения нового PSP.
SI = значение, которое требуется установить в поле со
смещением 2 в новом PSP.
4
ПРОЦЕСС ЗАВЕРШЕНИЯ РЕЗИДЕНТНОЙ ПРОГРАММЫ.
Сущность завершения резидентной программы без PSP
состоит в создании нового PSP и указании DOS использовать
этот PSP в качестве активного. При этом сам текст
резидентной части перемещается на начало старого PSP.
Рассмотрим последовательность действий при завершении
программы.
1. Освободить ENVIRONMENT, адрес которого находится в
PSP по смещению 2Ch. Вообще говоря, это действие не связано
с собственно процессом завершения резидентной программы без
PSP и рекомендуется для любого способа завершения
резидентных программ.
2. Изменить размер памяти, используемый программой,
указав в качестве нового размера длину резидентной части
программы в параграфах, а в качестве адреса модифицируемой
памяти - сегментный адрес PSP. Для выполнения используется
функция DOS 4Ah. Если резидентная часть начинается с начала
программы, то ее следует сначала сохранить, т.к. при
освобождении памяти в теле программы будет построен новый
MCB. Также целесообразно зарезервировать после резидентной
части участок длиной 16 байт для MCB, чтобы последующие
действия не уничтожили дальнейший код программы.
3. Вычисляется сегментный адрес для построения нового
PSP по формуле <длина резидентной части в
параграфах>+<сегментный адрес старого PSP>+1 (размер MCB в
параграфах).
4. Строится новый PSP по вычисленному сегментному
адресу с использованием функции 55h. В качестве значения SI
берется поле со смещением 2 в старом PSP.
5. Корректируется адрес родительского PSP в новом PSP
по смещению 16h. Значение выбирается из поля с таким же
смещением из старого PSP.
6. Новый PSP указывается DOS в качестве текущего с
использованием функции 50h.
7. Корректируется указатель на собственника памяти в
новом MCB по смещению 01h. MCB расположен по сегментному
адресу равному сегменту нового PSP минус 1. Значение
указателя устанавливается равным сегментному адресу нового
PSP.
8. Резидентная часть программы пересылается по адресу
сегмента старого PSP со смещением 0.
9. Выполняются необходимые действия для настройки
резидентной части. Их можно также выполнить заранее.
10. Программа завершается обычным образом по функции
DOS 04Ch.
5
Схематически этот метод изображен на 3-х рисунках.
Рисунок 1 показывает изменение в расположении блоков в
памяти при выполнении функции DOS 4Ah.
ЪДДВДДДДДДДДДДДДДДД¬ ЪДДВДДДДДДДДДДДДДДД¬
¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ MCB ¦ Ъ> На PSP <¬ ¦ ¦ MCB ¦
¦ ¦ ¦ ¦ родителя ¦ ¦ ¦ ¦
¦ ГДДДДДДДДДДДДДДДґ ¦ ¦ ¦ ГДДДДДДДДДДДДДДДґ
АД>¦ текущий ГДДЩ ¦ АД>¦ текущий ¦
¦ PSP ¦ АДДДДґ PSP ¦
ГДДДДДДДДДДДДДДДґ ГДДДДДДДДДДДДДДД¦
¦ ¦ Выполнение ¦ ПРОГРАММА ¦
¦ ¦ функции ГДДДДДДДДДДДДДДДґ
¦ ¦ DOS ¦ новый ¦
¦ ¦ 4Ah ¦ MCB ¦
¦ ¦ ¦ свободный ¦
¦ ПРОГРАММА ¦ ГДДДДДДДДДДДДДДДґ
¦ ¦ ¦ ¦
¦ ¦ ¦ ПРОГРАММА ¦
АДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДЩ
Рис. 1.
Рисунок 2 показывает изменение в расположении блоков в
памяти после выполнения функции DOS 55h и при коррекции
указателей.
Выполнение функции DOS 55h.
ЪДДВДДДДДДДДДДДДДДД¬ ЪДДВДДДДДДДДДДДДДДД¬
¦ ¦ ¦ Ъ> На PSP ¦ ¦ ¦
¦ ¦ MCB ¦ ¦ родителя ¦ ¦ MCB ¦
¦ ¦ ¦ ¦ ¦ ¦ ¦
¦ ГДДДДДДДДДДДДДДДґ ¦ ¦ ГДДДДДДДДДДДДДДДґ
АД>¦ текущий ГДЩ АД>¦ текущий ¦
¦ PSP ¦<ДД¬ ¦ PSP ¦
¦ ¦ ¦ ¦ ¦
ГДДДДДДДДДДДДДДД¦ ¦ ГДДДДДДДДДДДДДДД¦
¦ ПРОГРАММА ¦ ¦ ¦ ПРОГРАММА ¦
ГДДДДДДДДДДДДДДДґ ¦ ЪДД†ДДДДДДДДДДДДДДДґ
¦ новый ¦ ¦ Коррекция ¦ ¦ новый ¦
¦ MCB ¦ ¦ указателей ¦ ¦ MCB ¦
¦ свободный ¦ ¦ ¦ ¦ распределен ¦
ГДДДДДДДДДДДДДДДґ ¦ ¦ ГДДДДДДДДДДДДДДДґ
¦ новый ГДДДЩ АД>¦ новый ¦
¦ PSP ¦ На PSP <ДДДДґ PSP ¦
ГДДДДДДДДДДДДДДДґ родителя ГДДДДДДДДДДДДДДДґ
¦ ПРОГРАММА ¦ ¦ ПРОГРАММА ¦
АДДДДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДЩ
Рис. 2.
6
Рисунок 3 показывает изменение в расположении блоков в
памяти после выполнения функции DOS 50h.
Выполнение функции DOS 50h.
ЪДДВДДДДДДДДДДДДДДД¬
¦ ¦ ¦
¦ ¦ MCB ¦
¦ ¦ ¦
¦ ГДДДДДДДДДДДДДДДґДДДД¬
АД>¦ старый ¦ ¦
¦ PSP ¦ ГДДДД> Вся эта область доступна TSR.
ГДДДДДДДДДДДДДДДґ ¦
¦ ПРОГРАММА ¦ ¦
ЪДД†ДДДДДДДДДДДДДДДґДДДДЩ
¦ ¦ новый ¦
¦ ¦ MCB ¦
¦ ¦ распределен ¦
¦ ГДДДДДДДДДДДДДДДґ
АД>¦ текущий ГДДДДДДДД> На PSP родителя.
¦ PSP ¦
ГДДДДДДДДДДДДДДДґ
¦ ПРОГРАММА ¦
АДДДДДДДДДДДДДДДЩ
Рис. 3.
СОВМЕСТИМОСТЬ.
Данный метод опробован в различных совместимых
операционных средах:
- 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.
7
ПРИМЕР РЕЗИДЕНТНОЙ ПРОГРАММЫ БЕЗ PSP.
Для лучшего понимания порядка завершения резидентной
программы без PSP приведем пример.
page 60,132
title NONPSP - Резидентная программа без PSP
;==========================================================
;
; Пример построения резидентной программы без PSP
;
; Авторские права ГРУППЫ ПРОГРАММИСТОВ 2B
;
; Язык программирования: Ассемблер
; Транслятор : 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 10h ;размер MCB
;
PSPMCB db MCBlen dup (0) ;резервная область для MCB
SavRes db ResLen dup (0) ;область сохранения
; резидентной части
;
PspOld dw 0 ;для адреса старого PSP
PspNew dw 0 ;для адреса нового PSP
8
;
; сообщения
;
MsgInst label byte
db 0ah,0dh
db 'Программа установлена'
db 0ah,0dh
db '$'
MsgNoInst label byte
db 0ah,0dh
db 'Ошибка. Программа не установлена'
db 0ah,0dh
db '$'
;=========================================================