Главная · Поиск книг · Поступления книг · 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 ... 38 39 40 41 42 43 44  45 46 47 48 49 50 51 ... 198
         EXRTL может изменить значение бита переноса;  затем,  перед выхо-
         дом,  она  может скопировать флажки обратно в стек (включая новое
         значение флажка переноса).  Эти операции  позволяют  подпрограмме
         EXRTL использовать флажок переноса для сигнализации условий ошиб-
         ки для вызывающей программы,  используя инструкцию IRET для восс-
         тановления флажков из стека.

                     Листинг 3-6. Выполнение программы для RTL
         ----------------------------------------------------------------
         ;====== RTL_TEST.ASM - Этот файл вырабатывает .COM файл ========
         V_NUM   EQU     40h          ; эта RTL использует вектор 40h
         INCLUDE STDMAC.INC           ; включение файла макробиблиотеки
         ;====== СЕКЦИЯ ПРОГРАММНОГО КОДА ===============================
         code_seg SEGMENT
                 ASSUME cs:code_seg
                 ASSUME ds:code_seg
         main    PROC    FAR
                 ORG     0100h
         start:  mov     cx,3         ; начало при неправильном значении
         loop:   push    cx           ; код функции
                 int     V_NUM        ; вызов RTL
                 pop     cx           ; очистка параметра возврата
                 jnc     nxt          ; переход, если ошибки нет
                 @DisStr caserr       ; показать ошибку
         nxt:    dec     cx
                 jge     loop         ; цикл через 0
                 mov     ah,4Ch       ; завершение процесса
                 @DosCall
         caserr  db      'Case Error - Illegal Function Code',CR,LF,'$'
         main    ENDP
         code_seg ENDS
                 END     start

                                      - 3-41 -

             Последний вопрос, насколько полно может использовать подпрог-
         рамма EXRTL операционную систему MS-DOS,  когда получает управле-
         ние непосредственно из другой программы? В некоторых других рези-
         дентных программах,  представленных  в  следующих  разделах  этой
         книги, это  происходит не так.  Эти программы получают управление
         через прерывания аппаратных средств или прерывания MS-DOS.

                    Адрес   .----------------------.
                            |/\/\/\/\/\/\/\/\/\/\/\| Таблица векторов
                             /\/\/\/\/\/\/\/\/\/\/\  семейства микро-
                            |                      | процессора 8086
                            |----------------------|<---------------.
                   0000:0100|     IP или CS RTL    |--------------. |
                            |----------------------|              | |
                             \/\/\/\/\/\/\/\/\/\/\/               | |
                            |\/\/\/\/\/\/\/\/\/\/\/|              | |
                            |----------------------|<-------------  |
                            |     Элемент RTL      | Установленная  |
                             \/\/\/\/\/\/\/\/\/\/\/       RTL       |
                            |\/\/\/\/\/\/\/\/\/\/\/|                |
                 .----------|         IRET         |                |
                 |          |----------------------|                |
                 |           \/\/\/\/\/\/\/\/\/\/\/                 |
                 |          |\/\/\/\/\/\/\/\/\/\/\/| Программа      |
                 |          |----------------------|пользователя    |
                 |          |/\/\/\/\/\/\/\/\/\/\/\|                |
                 |           /\/\/\/\/\/\/\/\/\/\/\                 |
                  --------->|       Int 40h        |----------------
                            |/\/\/\/\/\/\/\/\/\/\/\|
                             /\/\/\/\/\/\/\/\/\/\/\
                            |----------------------|
                            |/\/\/\/\/\/\/\/\/\/\/\|
                             /\/\/\/\/\/\/\/\/\/\/\
                            |                      |
                             ----------------------

             Рис. 3-12. Доступ к библиотеке исполняющей системы (RTL)

               Как определить, установлены ли резидентные программы?

             До сих пор мы предполагали, что библиотека исполняющей систе-
         мы (RTL) должна быть загружена в  память, и  только  после  этого
         должны стартовать программы, которые ее используют. При некоторых
         обстоятельствах RTL может всегда находиться в памяти.  Чем загру-
         жать  повторную  копию  RTL,  загрузчик сначала должен определить
         загружена ли уже RTL в память,  и загружать ее только тогда, если
         она отсутствует в памяти. Имеется два способа определения наличия
         RTL в памяти, которые оба зависят от использования предварительно
         назначенного вектора прерывания для доступа к RTL.
             Первый  способ - чтение содержимого  вектора  прерывания  по-
         средством функции  с  кодом  35h "Получить вектор прерывания" для
         определения начального адреса подпрограммы обслуживания  прерыва-
         ния  (ISR  - Interrupt service routine).  Следующий шаг состоит в
         том,  чтобы поместить в регистры DS и SI начальный адрес устанав-
         ливаемой существующей подпрограммы.  Затем выполняется инструкция
         CMPS (сравнение строк) для сравнения  некоторого  количества бай-
         тов (в регистре CS) двух секций программы. Если результат сравне-
         ния положительный, то подпрограмма уже представлена в памяти. Ес-
         ли сравнение не произошло,  то подпрограмма не была установлена в
         памяти.  Эффективность этого способа намного упадет, если все RTL
         (или резидентные  подпрограммы) будут начинаться с одинаковой по-
         следовательности инструкций.  И,  наоборот,  эффективность  может
         сильно  возрасти,  если все резидентные подпрограммы будут содер-
         жать блок заголовка,  показанный в листинге 3-7,  и который  уни-
         кально идентифицирует каждую резидентную подпрограмму.
             Второй способ проверки наличия RTL или  резидентной  подпрог-
         раммы в памяти,  требует, чтобы все неиспользуемые векторы преры-
         вания (в больших системах от вектора 40h до  вектора  0FFh)  были
         установлены в известное состояние.  Это состояние может быть либо
         верхней, либо нижней памятью (0000:0000 или FFFF:FFFF), или адре-
         сом инструкции IRET. В MS-DOS версии 2.0 и выше вектор 28h всегда
         указывает на ячейку инструкции IRET,  хотя это не  гарантируется!
         Более элегантным решением для обработки   незапрошенных  прерыва-
         ний  и  инициализации всех неиспользуемых векторов прерываний для
         указания на эту подпрограмму  (смотри  главу  6  "Устанавливаемые
         драйверы  устройств") является установка драйвера псевдо-устройс-
         тва. Этот драйвер может затем содержать инструкцию IRET, отчет об
         ошибках,  выдаваемый на консоль,  или все,  что потребуется.  При
         постоянном распределении одного вектора для  постоянного указания
         на драйвер незапрошенных прерываний (например,  вектор 40h) прог-
         рамма установки может прочитать и сравнить этот вектор  и  вектор
         резидентной подпрограммы,  чтобы убедиться в том, была ли уже ре-
         зидентная программа установлена в памяти.





               Листинг 3-7. Идентификация входных строк подпрограммы
         ----------------------------------------------------------------

         enter: jmp start                ; обход области данных
                 db '<имя подпрограммы>' ; здесь задается имя подпр-мы
                 ...     ...             ; область данных
         start:  <начало программного кода>
                 ...     ...
         ----------------------------------------------------------------

                    Удаление резидентных подпрограмм из памяти

             Когда программа закончила использование RTL,  или когда рези-
         дентная подпрограмма больше не нужна,  может возникнуть необходи-
         мость  восстановления памяти,  которая была распределена для этой
         подпрограммы.  Наиболее  простым  способом  удаления  резидентной
         подпрограммы является перезагрузка системы.  Это позволит восста-
         новить все векторы, которые требует система, и возвратить системе
         всю  распределенную память.  Однако,  это очень решительный шаг и
         лучше зарезервировать его для безнадежных ситуаций.
             Удаление подпрограммы без перезагрузки системы необходимо вы-
         полнять с помощью следующих двух шагов:
             1. Отключение подпрограммы.
             2. Восстановление памяти.
             Первый шаг  состоит в установке в нулевое состояние вектора,

                                      - 3-43 -
         указывающего на подпрограмму.  Нулевое состояние для любых потен-
         циальных  пользователей  означает,  что подпрограмма больше недо-
         ступна. Если резидентная подпрограмма была расположена на участке
         памяти  ("заплате")  для  ранее существующего вектора,  то вектор
         должен быть восстановлен так, чтобы он указывал на первоначальную
         ячейку. Можно написать программу для восстановления вектора, если
         значение  старого вектора хранится где-нибудь в резидентной  под-
         программе, и программа восстановления может найти его.  Этот про-
         цесс сохранения вектора для его последующего  восстановления  де-
         монстрируется в листингах программ INIT28 (листинг 3-12) и REMOVE
         (листинг 3-13).
             Если память резидентной подпрограммы  управляется  с  помощью
         своего  собственного прерывания аппаратных средств (но не в форме
         "заплаты"), то перед удалением резидентной подпрограммы необходи-
         мо обеспечить невозможность возникновения прерывания от этого ус-
         тройства.  Можно изменить вектор в таблице или оставить его  так,
         как он есть.

          РЕГИСТРЫ                                       ВНЕШНИЙ СЕГМЕНТ
                                                       .----------------.
         AX:4B00 (шест.)<---Функция ВЫПОЛНИТЬ ПРОГРАММУ|       ...      |
                                                       |----------------|
         BX:Указатель на имя файла в ASCIIZ ---------->| имя файла/пути |
                                                       |  нулевой байт  |
         DX:Указатель на блок параметра --------.      |----------------|
                                                |      |       ...      |
          Адрес ENVIRONMENT (СРЕДА) | \/\/\/\/\/\/\/\/ xxxx:0000 .--------
         ---------. |
                   | ASCIIZ string 1 |<----.    |
                   | ASCIIZ string 2 |     |    |
                   |       ...       |     |    |        СЕГМЕНТ ДАННЫХ
                   | ASCIIZ string N |     |    |      .----------------.
                   |  нулевой байт   |     |    |      |        ...     |
                    -----------------      |     ----->|----------------|
                                            -----------|envir.seg или 0 |
                                                       |----------------|
         Текстовый буфер командной строки <------------|DWORD:указывает |
                                                       |      текст     |
                                                       |----------------|
         File Control Block 1:load @ 5Ch  <------------|DWORD:указывает |
         (FCB1-блок управления файлом 1:загрузка @ 5Ch)| FCB 1          |
                                                       |----------------|
         File Control  Block  2:load @ 6Ch <-----------|DWORD:указывает |
         (FCB2-блок управления файлом 2:загрузка @ 6Ch)| FCB 2          |
Предыдущая страница Следующая страница
1 ... 38 39 40 41 42 43 44  45 46 47 48 49 50 51 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама