На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 3 / Адреса завершения PSP. Таблица описателей файлов PSP Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Адреса завершения 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
         ----------------------------------------------------------------

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz