тем она получает адрес PSP и из PSP получает адрес таблицы описа-
телей. Используя myfile в качестве индекса таблицы описателей,
программа получает индекс таблицы файлов системы myfile и запоми-
нает его в индексе, назначенном для stdout (стандартный вывод),
выполняя переназначение. Оставшаяся часть программы "поворачива-
ет" процесс и заканчивает работу закрытием описателя myfile.
Листинг 3-2. Фрагмент программы для переключения таблицы
описателей файла
----------------------------------------------------------------
; Этот листинг передает таблицу описателей файла, назначенную
; по умолчанию, в область, адрес которой указывается в ES:DI.
; Размер новой таблицы подразумевается в CX. Подразумевается
; MS-DOS версии 3.xx (для функции "Get PSP Address" - получить
; адрес PSP). Регистры AX и BX не сохраняются.
;
push ds ; сохранение DS
push si ; сохранение SI
push di ; сохранение смещения новой таблицы
push cx ; сохранение размера новой таблицы
mov ah,62h ; получение PSP
int 21h ; возврат PSP в BX
mov ds,bx ; адрес PSP
;
; Получение размера и адреса текущей таблицы
mov bx,032h ; адрес размера таблицы
mov cx,[bx] ; получение размера таблицы
push ds ; сохранение адреса PSP
lds si,[bx]2 ; получение адреса текущей таблицы
; Копирование старой таблицы из DS:DI на новое место по ES:DI
cld ; пересылка в прямом направлении
rep movsb ; пересылка таблицы на новое место
;
; Восстановление размера и положения новой таблицы и обновление
; PSP
pop ds ; восстановление адреса PSP
pop cx ; восстановление размера новой таблицы
pop di ; восстановление смещения новой таблицы
mov [bx]2,di ; запоминание смещения новой таблицы
mov [bx]4,es ; запоминание сегмента новой таблицы
mov [bx],cx ; запоминание размера новой таблицы
pop si ; восстановление первоначального SI
pop ds ; восстановление первоначального DS
----------------------------------------------------------------
Листинг 3-3. Фрагмент программы для переназначения
StdOut в файл
----------------------------------------------------------------
; Этот листинг открывает описатель файла или устройства с
; именем "myfile" и заменяет описатель StdOut вновь открытым
; описателем. Вход подразумевается с DS и ES, указывающих на
; сегмент данных. Переменные следующих данных предполагаются
; определенными:
;
StdOut equ 1 ; код для описателя StdOut
- 3-21 -
Handle dw ? ; новая переменная описателя
Outhand db ? ; переменная описателя StdOut
MyFile db 'filename.ext',0
;
; Открытие описателя для файла/устройства, находящегося в
; myfile
lea dx,MyFile ; имя
mov al,2 ; доступ чтение/запись
mov ah,03dh ; функция OPEN - открыть
int 21h
jc OpenError
mov Handle,ax ; сохранение описателя
;
; Передача описателя файла/устройства в описателю StdOut.
push es ; сохранение ES
mov ah,62h ; получение PSP
int 21h
mov es,bx ; ES указывает на PSP
les bx,es:[bx].PSPHandlePntr
;
; ES:BX теперь указывает на таблицу описателя файла
mov al,es:[bx].StdOut ; чтение описателя StdOut и
mov Outhand,al ; сохранение
mov di,Handle ; считанного индекса описателя
mov al,es:[bx+di] ; считывание входа описателя
mov es:[bx].StdOut,al ; запом-е как описателя StdOut
pop es
;
; Восстановление первоначальной описателя StdOut
push es ; сохранение ES
mov ah,62h ; получение PSP
int 21h
mov es,bx ; ES указывает на PSP
les bx,es:[bx].PSPHandlePntr
;
; ES:BX указывает теперь на таблицу описателя файла
mov al,Outhand ; считывание описателя StdOut
mov es:[bx].StdOut,al ; запоминание описателя StdOut
pop es
;
; Закрытие переназначенного файла
mov bx,Handle ; описателя для файла или устройства
mov ah,03eh ; функция CLOSE - закрыть
int 21h
----------------------------------------------------------------
SHOWMEM и указатель адреса среды PSP
Другим полезным значением, сохраняемым в PSP, является адрес
сегмента блока среды процесса. Мы не возвращались к этому входу в
связи с тем, что он требовал последующего разъяснения, но так как
теперь мы обладаем полной информацией, необходимой для понимания
всей программы SHOWMEM, включая подпрограмму ShowMCBOwner, то:
- найдите начальный блок управления памятью, используя преры-
вание int 52h;
- используйте поле владельца в блоке MCB в качестве адреса
PSP;
- проверьте PSP путем проверки первых двух байтов для преры-
вания int 20h;
- если владельцем MCB является PSP, то извлеките адрес среды.
Если PSP не является владельцем, то владельцем должна быть
MS-DOS;
- вычтите единицу из адреса сегмента среды для получения MCB
среды, и извлеките из него размер среды;
- проверьте среду на наличие двойного нуля, который сигнали-
зирует о конце строк ASCIIZ;
- проверьте процесс пользователя на наличие сигнатуры 0001.
Если сигнатура 0001 найдена, то печатайте следующее имя. Если
сигнатура 0001 отсутствует, то процесс должен быть COMMAND.COM
или эквивалентным командным процессом;
- если текущий MCB не является последним, то найдите следую-
щий MCB путем добавления размера блока (плюс 1) к адресу MCB;
- повторите выполнение со второго шага.
Программа SHOWMEM демонстрирует внутренние взаимосвязи, су-
ществующие внутри DOS и показывает как можно перейти от блока уп-
равления памятью к PSP, к блоку среды и обратно к MCB среды, вы-
бирая необходимые данные.
Функции для манипулирования PSP
MS-DOS содержит функции, относящиеся непосредственно к пре-
фиксу программного сегмента. Эти функции перечислены в таб. 3-2.
Для этих функций, которые получают и устанавливают PSP, текущий
PSP определяется MS-DOS не по программному сегменту, выполняемому
в данное время.
Например, предположим, что выполняется программа MYPROG, ког-
да получает управление установленная подпрограмма (TSR, если
угодно) и выдает вызов функции GET PSP (получить PSP - функция с
кодом 62h). В этом случае MS-DOS возвращает значение PSP для
прерванной программы MYPROG. Это происходит потому, что после то-
го как подпрограмма резидентной памяти выполнит функцию Keep
Process (сохранить процесс) или завершить и оставить резидентной,
она еще некоторое время будет считаться активной. MS-DOS считает
последнюю загруженную программу текущей активной программой.
Если важно, чтобы TSR имела доступ к своему собственному PSP,
то для этого может быть использована недокументированная функция
SET PSP (установить PSP - функция с кодом 50h). Когда TSR загру-
жается в первый раз, она должна сохранить значение своего PSP.
Затем , когда TSR позднее получит управление, PSP прерванной
программы может быть определен с помощью функции 62h (GET PSP-по-
лучить PSP). Это значение должно быть сохранено и активизирован
собственный PSP TSR с помощью функции 50h (SET PSP - установить
PSP). После выполнения TSR, она должна восстановить первоначаль-
ный PSP с помощью функции SET PSP (установить PSP).
- 3-23 -
Таблица 3-2
Функции прерываний int 21h для сегмента программого префикса
________________________________________________________________
|
Функция| Назначение
________|_______________________________________________________
26h | Создание блока PSP. Устаревшее использование
________|_______________________________________________________
50h | Установка текущего PSP. Недокументированная. BX содер-
| жит адрес сегмента действительного PSP. Эта функция
| заставляет новый PSP (BX) стать активным PSP для
| MS-DOS. Последовательные обращения к MS-DOS, ссылающи-
| еся к данным PSP, также как таблица описателя файла,
| будут использовать новый PSP.
________|_______________________________________________________
51h | Получить сегмент PSP. Недокументированная. Возвращает
| адрес текущего сегмента PSP в регистре BX. Это тоже
| самое, что и функция 62h, но она также доступна и в
| более ранних версиях MS-DOS 3.00. Ненадежна для вызова
| из TSR. Вместо этой функции рекомендуется использовать
| функцию 62h.
________|_______________________________________________________
55h | Получить копию PSP. Недокументированная. Функция почти
| идентична функции 26h. DX содержит адрес сегмента но-
| вого PSP. Однако, эта функция будет также устанавли-
| вать поле владельца нового PSP для адреса сегмента те-
| кущего PSP. Т.к. это недокументированная функция и по-
| лезна только при загрузке новой программы, то вместо
| нее рекомендуется использовать функцию EXEC (выпол-
| нить) с кодом 4Bh.
________|_______________________________________________________
62h | Получить текущий PSP. MS-DOS версии 3.00 и последующие
| версии. Возвращает адрес сегмента текущего PSP в ре-
| гистре BX.
________|_______________________________________________________
Файлы процессов MS-DOS: .EXE в сравнении с .COM
Как известно, в MS-DOS файлы исполнимой программы могут быть
в двух вариантах: файлы типа .COM и файлы типа .EXE. Рисунки 2-3
(в главе 2) и 3-6 иллюстрируют некоторые различия между этими
двумя типами файлов. Для MS-DOS различия проявляются в других
формах.
Тип файла .EXE - это в действительности "естественный" режим