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










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

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

Рабочая таблица файлов (JFT)

В большинстве случаев PSP будет содержать саму рабочую таблицу файлов. По умолчанию JFT позволяет открыть одновременно 20 файлов, но имеется возможность создания альтернативной JFT для увеличения максимального количества открытых файлов. В DOS 3.3 для этого имеется специальная функция (int 21h AH=67h). В DOS версии ниже 3.3 можно изменять адрес JFT в PSP вручную. DOS для ввода/вывода будет использовать заново определенную JFT, но будет иметь трудности клонирования этой JFT при обработке запроса загрузки (int 21h AH=4bh).


Рабочая таблица файлов заносит описатели в качестве входов таблицы файловой системы. Каждый вход JFT занимает один байт. Если вход не использован, он содержит 0FFh; в противном случае он содержит системный номер файла(SFN), который используется как индекс в таблице файловой системы. DOS использует описатель файла в JFT как индекс.


Листинги 4-16 и 4-17 иллюстрируют связи между PSP, JFT, SFN и SFT. Первая подпрограмма принимает описатель в BX и возвращает соответствующий системный номер файла (SFN) в AX. Подпрограмма использует функцию BIOS AH=62h для размещения текущего PSP, когда получает адрес JFT из PSP, и в конечном счете использует описатель, как индекс в JFT. Макроопределения pushr и popr сохраняют и перезапоминают регистры, описанные как аргументы. Если встретилась ошибка, то эта подпрограмма возвращает флаг переноса установленным (CY=1).


Вторая подпрограмма принимает SFN в AX и возвращает адрес соответствующего входа SFT в ES:DI. Она получает адрес "списка списков" с функцией AH=52h и затем получает описатель списка заголовков SFT в ES:DI. Каждый блок имеет "следующее" поле и часть оглавления, которая показывает, сколько входов в этом блоке. Эта подпрограмма просматривает цепочку блоков SFT до тех пор, пока не найдет блок, содержащий вход SFT. Если описатель неверен или если SFT испорчена, подпрограмма возвращает флаг переноса установленным.



               Листинг 4-16.  Использование описателя для получения
                              номера системного файла
         ----------------------------------------------------------------

         GetSFN          PROC  NEAR
                         pushr ; макрокоманда сохранения
                                            ; регистров
                         mov   ah,62h...    ; получить текущий PSP
                         int   21h
                         mov   ds,bx        ; ds <== текущий PSP
                         pop   bx           ; описатель
                         cmp   bx,0ffh      ; проверка описателя
                         Jz    BadHandle    ; описатель не может быть
                                            ; отрицательным
                         cmp   bx,ds:PSP_W_JFTSize
                                            ; описатель слишком велик?
                         jge   BadHandle    ; если ge - да
                         les   di,ds:PSP_D_JFTAddr
                                            ; es:di <== JFT
                         mov   al,es:[di][bx] ; al <== SFN (описатель)
                         cbw                ; ax <== SFN (описатель)
                         clc                ; успешная индикация
         Done: popr               ; восстановление регистров
                         ret                ; возврат
         BadHandle       stc                ; ошибка индикации
                         jmp   SHORT Done   ; общий выход
         GetSFN          ENDP
         ----------------------------------------------------------------


                   Листинг 4-17. Поиск системной таблицы файлов
         ----------------------------------------------------------------

         LocateSFT       PROC   NEAR
                         push   ax         ; сохранение SFN
                         mov    ah,52h     ; запрос адреса
                         int    21h        ; списка списков
         ;
         ;        es:di <== 1-ый блок описателя оглавления списка SFT
         ;
                         les    di,es:[bx].DOS_D_HDLSFT
                         pop    ax         ; восстановление SFN
                         xor    bx,bx      ; bx <== 0
         _l0             cmp    di,0ffffh  ; конец последовательности
                         jz     _l2        ; если z - да
         ;
         ;               bx <==  первый SFN в следующем блоке
         ;
                         add    bx,es:[di].SFTBLK_W_Count
                         cmp    ax,bx       ; SFN в этом блоке?
                         jl     _l1         ; если l - да
         ;
         ;               es;ds <== следующий блок SFT
         ;
                         les    di,es:[di].SFTBLK_D_Next
                         jmp    SHORT _l0    ; продолжение поиска
         ;
         ;               bx <== первый SFN этого блока
         ;
         _l1             sub    bx,es:[di].SFTBLK_W_Count
                         sub    ax,bx        ; ax <== смещение блока
                         mov    bl,SFT_K_SIZE; bl <== размер входа
                         mul    bl           ; перевод смещения в байты
                         add    di,ax        ; di <== смещение в блоке
                                             ; (почти)
                         add    di,SFTBLK_K_Size ; добавить сверху
                         clc                 ; успешная индикация
                         ret                 ; возврат
         _l2             stc                 ; ошибка индикации
                         ret                 ; возврат
         LocateSFT       ENDP
         ----------------------------------------------------------------

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

Hosted by uCoz