Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Различные авторы Весь текст 2311.07 Kb

Программирование и кодирование

Предыдущая страница Следующая страница
1 ... 53 54 55 56 57 58 59  60 61 62 63 64 65 66 ... 198
         SFT_M_Written   EQU  0040h ; (FILE) пользовательский файл
         SFT_M_DriveMask EQU  003fh ; (FILE) маска для битов драйвера (0-5)
         ----------------------------------------------------------------

                        Сегмент программного префикса (PSP)

              Когда DOS загружает программу,  он создает сегмент  префикса
         программы.  В  предыдущей главе описаны многие из полей PSP.  DOS
         всегда помещает PSP на шестнадцатибайтовую границу параграфа, так
         что он может быть описан, как значение длиной в слово (сегмент, а
         смещение ноль).  Команда DOS 62h возвращает адрес текущего PSP  в
         регистре  BX (недокументированная функция AH=51h также возвращает
         PSP в BX).

                                      - 4-21 -
              Листинг 4-15   показывает   структуру    PSP.    Поля    PSP
         PSP_D_JFTAddr и PSP_W_JFTSize содержат  адрес  и  размер  рабочей
         таблицы  файлов  (JFT).  PSP  содержит также копию (по умолчанию)
         JFT,  начинающуюся с JFT_T_JFT.  DOS использует некоторые  другие
         поля  PSP  для обработки критических ошибок и запроса завершения;
         подробнее об этих полях позднее.


                            Листинг 4-15. Структура PSP
         ----------------------------------------------------------------

         PSP   STRUC
         PSP_W_int20     DW    0cd20h ; [00] команда int 20
         PSP_W_MemSiz    DW    0      ; [02] начало памяти (para)
         PSP_B_Unused0   DB    0      ; [04] неизвестно
         PSP_T_Call      DB    09aH,0f0h ; [05] дальний вызов DOS
                         DB    0feH,01dh,0f0h ; диспетчер (CPM relic)
         PSP_D_Term      DD    0      ; [0a] конечный адрес
         PSP_D_Break     DD    0      ; [0e] адрес прерывания
         PSP_D_CritErr   DD    0      ; [12] критическая ошибка
         PSP_W_Parent    DW    0      ; [16] родительский PSP
         PSP_T_JFT       DB    14h   DUP   (0ffn) ; [18] таблица JFT
         PSP_W_Envron    DW    0      ; [2c] окружение
         PSP_D_SSSP      DD    0      ; [2e] SS:SP пользователя на
                                      ; время int 21
         PSP_W_JFTSize   DW    14h    ; [32] размер JFT
         PSP_D_JFTAddr   DD    0      ; [34] адрес JFT
         PSP_D_NextPSP   DW    0ffffH,0ffffh ; [38] не применяется
         PSP_T_Unused2   DB    14h    DUP  (0) ; [3c] не применяется
         PSP_W_Int21     DW    0cd21h ; [50]
         PSP_B_Retf      DB    0      ; [52]
         PSP_T_Unused3   DB    9     DUP  (0) ; [53]
         PSP_T_Parm1     DB    10h   DUP  (0) ; [5c] форматировано param 1
         PSP_T_Parm2     DB    14h   DUP  (0) ; [6c] форматировано param 2
         PSP_T_DTA       DB    80h   DUP  (0) ; [80] по умолчанию DTA
         PSP   ENDS
         ----------------------------------------------------------------

                           Рабочая таблица файлов (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 и возвращает

                                      - 4-22 -
         соответствующий системный  номер  файла (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
         ;

                                      - 4-23 -
                         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
         ----------------------------------------------------------------

                              Диспетчер BIOS, Int 21h

              Когда загружается  DOS,  IBMDOS  инициализирует  для int 21h
         вход IVT, чтобы указать на код внутри загрузочного модуля IBMDOS.
         ISR  обрабатывает все запросы int 21h.  Так как эта программа пе-
         реключает стеки и использует статические переменные,  она нереен-
         терабельна. Если TSR запрашивает обслуживание BIOS в неподходящее
         время, она испортит сохраненную DOS информацию о программе перед-
         него плана.  Результаты этого разрушения обычно катастрофические.
         Если Вам повезет,  Ваша система гробанется, не испортив Ваш диск.
              Обработка Int 21h начинается с прерываний, запрещенных в ре-
         зультате команды  INT.  Диспетчер  содержит  таблицу  действующих
         подпрограмм, которые завершают обработку различных запросов BIOS.
         Она содержит точки входа для каждой действующей функции  int 21h.
         Каждой строке этой таблицы непосредственно предшествует байт, со-
         держащий номер входа таблицы. В конечном счете DOS использует код
         функции в AH,  как индекс в этой таблице и сначала проверяет зна-
         чение,  переданное в AH.  Если запрос не выполнен,  то  диспетчер
         возвращает ошибку.
              Диспетчер Int 21h немедленно обслуживает запросы функций:
         AH=51h (недокументированная - получить текущий PSP),
         AH=62h (документированная - получить текущий PSP),
         AH=50h  (недокументированная  -  получить  текущий PSP),
         AH=33h (получить/установить прерывание).

                                      - 4-24 -
         Так как диспетчер не переключает стеки и не сохраняет контекстную
         информацию в статических переменных,  эти запросы всегда безопас-
         ны.
              Все по-другому,  если запрос не является одним из этих четы-
         рех  немедленно обслуживаемых запросов (почти все остальные функ-
         ции Int 21h).  DOS cохраняет все регистры в текущем стеке, сохра-
         няет   текущее   содержание  DS:BX  в  статической  переменной  и
         увеличивает флаг критического  интервала  (известный  также,  как
         InDOS).  Для  продолжения обработки запроса BIOS диспетчеру нужны
         регистры DS и BX;  DOS будет перезагружать эти регистры перед пе-
         редачей управления подпрограмме, которые будут завершать обработ-
         ку запроса.
              В это  время  регистры  SS:SP  все  еще содержат адрес стека
         программы переднего плана.  DOS записывает в статических перемен-
         ных значения SS:SP для текущего и предшествующего входа (то есть
         соответствующие последние значения SS:SP  диспетчера).  Диспетчер
Предыдущая страница Следующая страница
1 ... 53 54 55 56 57 58 59  60 61 62 63 64 65 66 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама