|
|
|
|
Адреса завершения PSP. Таблица описателей файлов PSP
Таблица 3-1 показывает три "адреса завершения", хранимые в байтах от 0Ah до 15h PSP. Как уже объяснялось выше, эти копии: адреса завершения
программы, адреса выхода по нажатию клавиш Control-Break и адреса выхода по критической ошибке выбираются из действительных векторов прерываний,
размещаемых в int 22h,int 23h и int 24h. Чтобы воздействовать на поведение системы во время ситуации завершения (такой как, например, выход по
внутреннему прерыванию CONTROL-BREAK/CONTROL-C) программисту требуется изменить основные векторы прерываний. Это можно сделать, используя для получения
и изменения этих адресов функции "Установить вектор" (Set Vector - код 25h) и "Получить вектор" (Get Vector - код 35h).
С обработкой файлов в сегменте программного префикса связаны три "недокументируемых" элемента: адрес таблицы описателей, указатель описателей и
счетчик описателей. Как увидим потом, эти элементы являются относительными.
Адрес таблицы описателей содержит указатель длины на таблицу, шириной в несколько байт в памяти, размер которой задается счетчиком описателей.
Каждый байтовый элемент этой таблицы является индикатором описателей, которая может быть открыта для файла или устройства.
Таблица 3-1
Содержимое сегмента программного префикса
________________________________________________________________
Шестнадцатиричные|
-----------------| Содержимое
смещение| размер |
________|________|______________________________________________
00 | 2 | Прерывание int 20h. Содержит инструкцию пре-
| | рывания int 20h (байты CD 20 - шестнадцати-
| | ричные значения). Устаревшее использование.
| | Программист вместо завершения должен исполь-
| | зовать функцию 4Ch, прерывание int 21h.
________|________|______________________________________________
02 | 2 | Вершина памяти. Содержит адрес сегмента, сле-
| | дующего за памятью программы. Это может быть
| | адрес старой памяти DOS (такой как А000) или
| | адрес следующего доступного блока управления
| | памятью.
________|________|______________________________________________
04 | 1 | Зарезервирован.
________|________|______________________________________________
05 | 5 | Длинный вызов диспетчера функций MS-DOS. Со-
| | держит длинный переход к диспетчеру функций
| | MS-DOS для использования с программами типа
| | CP/M. Устаревшее использование. Программы
| | должны вместо вызова MS-DOS использовать пре-
| | рывание int 21h.
________|________|______________________________________________
06 | 2 | Доступная память. Часть смещения длинного вы-
| | зова также содержит количество байтов, дос-
| | тупных в кодовом сегменте программы.
________|________|______________________________________________
0A | 4 | Адрес завершения программы. Копия адреса пре-
| | рывания int 22h (IP,CS), по которому переда-
| | ется управление, когда вводятся Control-Break
| | или Control-C.
________|________|______________________________________________
0E | 4 | Адрес выхода Control-Break. Копия адреса пре-
| | рывания int 23h (IP,CS), по которому переда-
| | ется управление, когда вводятся Control-Break
| | или Control-C.
12 | 4 | Адрес выхода по критической ошибке. Копия ад-
| | реса прерывания int 24h (IP,CS), по которому
| | передается управление, когда во время обра-
| | ботки обнаруживается критическая ошибка.
________|________|______________________________________________
16 | 2 | Префикс программного сегмента владельца. Это
| | сегментный адрес сегмента программного префи-
| | кса владельца. Для процессов, не имеющих вла-
| | дельца, это адрес текущего PSP.
________|________|______________________________________________
18 | 14 | Таблица описателей файла. Содержит 20 одиноч-
| | ных байтов "обработки" (индикаторов) в табли-
| | це файлов системы. Первыми 5 из них являются:
| | STDIN, STDOUT, STDERR, AUXIO и LSTOUT. Смотри
| | текст для более подробного объяснения.
________|________|______________________________________________
2C | 2 | Адрес среды. Адрес сегмента блока среды про-
| | цесса.
________|________|______________________________________________
2E | 4 | Память переключателя стека. Используется для
| | хранения стекового сегмента процесса и указа-
| | теля (SS:SP), когда процесс выполняет опера-
| | ции в стеке MS-DOS.
________|________|______________________________________________
32 | 2 | Счетчик описателей. Максимальное количество
| | элементов, допускаемое в таблице описателей
| | файла. По умолчанию принимается значение 20.
________|________|______________________________________________
34 | 4 | Адрес таблицы описателей.Длинный указатель на
| | таблицу описателей файла.По умолчанию в теку-
| | щем PSP принимается значение смещения 18 (ше-
| | стнадцатиричное значение).
_______|_______________________________________________________
38 | 18 | Зарезервировано.
________|________|______________________________________________
50 | 3 | Прерывание диспетчера функций. Содержит код
| | для прерывания int 21h вызова диспетчера фун-
| | кций MS-DOS, следующего по выходу far RET.
________|________|______________________________________________
53 | 2 | Зарезервировано.
________|________|______________________________________________
55 | 7 | Расширение блока управления файлом. Поля рас-
| | ширения для блока #1 управления файлом. Уста-
| | ревшее использование. Программы должны ис-
| | пользовать вместо описателя файла. Для полу-
| | чения более подробной информации по FCB (File
| | control block - блок управления файлом) обра-
| | титесь к руководствам по MS-DOS).
________|________|______________________________________________
5C | 10 | Блок управления файлом номер 1. Содержит не-
| | открытый блок FCB #1. Устаревшее использова-
| | ние и в результате может привести к разруше-
| | нию FCB #2 и длины командной строки. Пути
| | имен файлов не поддерживаются. Вместо этого
| | программы должны использовать описатели фай-
| | лов. Для получения более подробной информации
| | по FCB, обратитесь к руководствам по MS-DOS.
________|________|______________________________________________
6C | 10 | Блок управления файлом номер 2. Содержит не-
| | открытый блок FCB #2. Устаревшее использова-
| | ние и в результате может привести к разруше-
| | нию параметров командной строки. Вместо это-
| | го программы должны использовать описатели
| | файлов. Для получения более подробной инфор-
| | мации по FCB, обратитесь к руководствам по
| | MS-DOS.
________|________|______________________________________________
7C | 4 | Зарезервировано.
________|________|______________________________________________
80 | 80 | Дисковая область передачи, назначаемая по
| | умолчанию. Перекрывает при использовании
| | строку текста командной строки.
________|________|______________________________________________
80 | 1 | Длина командной строки. Длина текстовой стро-
| | ки, которая была набрана следом за именем
| | программы, минус любые переназначенные симво-
| | лы или параметры.
________|________|______________________________________________
81 | 7F | Буфер командной строки. Текстовая строка, ко-
| | торая была введена следом за именем программы.
| | Символы переназначения (< и >) и их соответст-
| | вующие имена файлов в этой области не появля-
| | ются, т.к. переназначение прозрачно для прик-
| | ладной программы.
________|________|______________________________________________
|
Открытые описатели сохраняют свои показания в таблице файлов системы. Неиспользуемые элементы в таблице помечаются шестнадцатиричным значением
0FF. Первые пять обработок в таблице описателей файлов зарезервированы за стандартными устройствами: STDIN (стандартный ввод), STDOUT (стандартный
вывод), STDERR (стандартная ошибка), AUXIO (вспомогательный ввод-вывод) и LSTOUT (стандартный вывод на печать) и открываются при запуске процесса.
Все показания отсчитываются от первоначального нулевого значения.
Рис.3-8 показывает состояние таблицы описателя файла, принятой по умолчанию, сразу же после успешного открытия файла myfile (мой файл). Таблица
описателя файла, принимаемая по умолчанию, является двадцатибайтовой таблицей, размещенной в PSP по смещению 18 (шестнадцатиричное значение). Этот
адрес запоминается в адресе таблицы описателя при запуске процесса. В связи с тем, что первые пять обработок зарезервированы за стандартными
устройствами, остается только 15 обработок, доступных для файлов или других устройств.
.00h-----------02h-------------------05h-----------------------.
|int 20h |Вершина памяти | 00 | Далекий вызов MS-DOS |
-------------|0Ah----------------------0Eh--------------------|
|Адрес завершения |Адрес выхода Ctrl-Break|
|12h---------------------|16h--------------------
|Адр.вых. по крит. ошибке|PSP владельца|
.18h-------------------------------------------------|
|Таблица описателя файла |
|----------------------------------------------------|
|Таблица описателя файла (продолжение) |
|-------------------------------2Ch-----2Eh--------------------.
|Таблица описателя файла(конец)|Среда |Начальный адрес стека |
--------------32h-------------|34h----------------------------
|Счетчик описат. |Указатель таб.описат.|
.38h-------------------------------------------------|
|Зарезервированная область (длиной 40 байт) |
----------------------------------------------------
.50h-----------------53h----------55h----------------.
|Функция int 21h |Зарезерв. |Расширение FCB |
|----------------------------5Ch---------------------|
|Расширение FCB(продолжение)|Блок управл-я файлом #1 |
|----------------------------------------------------|
|Блок управления файлом #1 (продолжение) |
|----------------------------6Ch---------------------|
|Блок управления файлом #1 |Блок управл-я файлом #2 |
|----------------------------------------------------|
|Блок управления файлом #2 (продолжение) |
|----------------------------7Ch---------------------|
|Блок управления файлом #2 |Зарезервированная обл. |
|80Ch-81Ch-------------------------------------------|
|Дл. |Буфер команд (длиной 127 байт) |
----------------------------------------------------
Рис.3-7. Структура PSP
|
На Рис.3-8 значение описателя, возвращаемое при успешном вы-
полнении функции OPEN, равно 0005, которое означает, что файлу с
именем myfile назначен шестой элемент (вход) в таблице описате-
ля файлов процесса. При обращении шестой вход содержит значение
03, которое означает, что файлу myfile был назначен четвертый
вход в таблице файлов системы. Рис.3-8 также демонстрирует ис-
пользование первых трех описателей с целью показа назначения
для одного и того же входа в системной таблице файлов нескольких
обработок. Максимальное количество входов в системную таблицу
файлов устанавливается с помощью предложения FILES = в файле кон-
фигурации системы CONFIG.SYS.
.34h----------------------------. .--------------.
| Указатель таблицы описателя | | Описатель AX |
| PS Segment:0018 (шестнадц.) | | OPEN = 0005 |
------------------------------- --------------
| |
-------------------------------
|
0 1 2 3 4 5 v 6 7
.-------------------------------------------------------.
|18h | | | | |Таб.описател.файлов |
| STDIN|STDOUT|STDERR| AUXIO|LSTOUT|myfile|(не использ.)|
| 01 | 01 | 01 | 00 | 02 | 03 | FF | FF |
-------------------------------------------------------
| | | | | |
|------------- | | |
|Табл. файлов системы| | |
| .--------------. | | |
| | AUX 0 |<- | |
| |--------------| | |
->| CON 1 | | |
|--------------| | |
| PRN 2 |<-------- |
|--------------| |
| MYFILE 3 |<---------------
|--------------|
|Не использ.4 |
--------------
Рис.3-8. Таблица описателей файлов PSP
|
В большинстве ситуаций пользователю никогда нет необходимости
быть осведомленным об этих устройствах, однако, существуют две
ситуации, когда эти знания полезны.
Первая ситуация возникает, когда программа пользователя тре-
бует больше описателей, чем может быть открыто в данное время.
Так как по умолчанию таблица описателей файлов поддерживает толь-
ко 20 описателей и т.к. 5 описателей уже присвоены, то практичес-
ки невозможно так далеко все предугадать. Тем не менее, чтобы
обойти это ограничение, программа должна установить свои собс-
твенные расширенные таблицы описателей файлов, как показано во
фрагменте программы в листинге 3-2.
При второй ситуации листинг 3-2 предполагает, что для прог-
раммы использовано размещение новой таблицы и, кроме того, пред-
полагает, что таблица была предварительно загружена с кодами 0FF
(коды неиспользуемых описателей). Программа сначала определяет
ячейки PSP, используя функцию 62h. Из PSP находится размер и
ячейки существующей таблицы описателей файлов, и старая таблица
копируется в новую таблицу. Новый адрес таблицы и ее размер сох-
раняются в соответствующих полях PSP и обмен завершается.
Другой возможностью, предоставляемой этим механизмом, являет-
ся то, что программист теперь управляет переназначением ввода и
вывода программы. В MS-DOS переназначение выполняется простым из-
менением драйвера, связанного с конкретным устройством. Этот спо-
соб даже работает для переназначения ввода и вывода, выполняемого
со старыми, необрабатываемыми вызовами ввода и вывода (такими как
функция 09h "Отобразить строку").
Листинг 3-3 демонстрирует как устройство stdout (стандартный
- 3-20 -
вывод) переназначается в файл или устройство myfile (мой файл).
Программа сначала открывает имя myfile и сохраняет описатель. За-
тем она получает адрес 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
----------------------------------------------------------------
|
|
|