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










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

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

Внесение "заплат" в векторы прерываний

Резидентные подпрограммы активизируются в одном из двух случаев: они инициирутся с помощью прерываний аппаратных средств (управление событиями), или они должна поместить "заплату" в существующую систему (управление перехватом). Возможна также комбинация этих способов, где точка "заплаты" является одним из прерываний аппаратных средств. Если используемая система не поддерживает прерывания аппаратных средств, то следует использовать способ "заплат".


Для доступа (с некоторыми сложностями) к резидентным подпрограммам могут быть использованы прерывания аппаратных средств, не используемые операционной системой MS-DOS. До тех пор, пока программа не осуществляет вызов MS-DOS, никаких системных конфликтов не произойдет. Если аппаратные средства системы доступны с помощью резидентной подпрограммы, то она должна проверить, что в это время нет больше доступных аппаратных средств, и быть осторожной при восстановлении аппаратного средства в его исходное состояние. Примером минимального влияния подпрограммы управления прерываниями является программа сохранения всех регистров текущего выполнения программы в зарезервированном разделе памяти, когда происходит внешнее прерывание. Такая подпрограмма полезна при отладке программ реального времени. Однако, если используемое прерывание также используется системой, то подпрограмма должна принимать во внимание управление перехватом, потому что резидентная подпрограмма установлена с "заплатой".


Способ "заплат" является способом вставки резидентных подпрограмм в обычное исполнение системы в данной точке так, чтобы доступ в эту точку осуществлялся через резидентную подпрограмму. Примером вставки "заплат", вызывающей аппаратное прерывание, является установка резидентной подпрограммы управления клавиатурой. Для этого вектор прерывания клавиатуры изменяется на точку для резидентной подпрограммы. Значение предыдущего вектора клавиатуры запоминается в адресе назначения инструкции перехода far (далекий), которая используется при выходе из подпрограммы резидентной памяти. Когда происходит прерывание клавиатуры, начинается выполнение резидентной подпрограммы. После завершения обработки прерывания, резидентная подпрограмма передает управление драйверу клавиатуры. Если резидентная подпрограмма действительно использует ввод клавиатуры в некоторых случаях, которые не может продолжить драйвер клавиатуры, то резидентная подпрограмма должна сама обслужить и очистить прерывание, и затем вернуться в вызывающую программу по инструкции IRET. Во всех случаях резидентная подпрограмма должна сохранять контекст прерванной программы.


Другими возможными точками вставки "заплат", которые не выполняют использование прерываний аппаратных средств, является вставка "заплат" в один из векторов прерывания программного обеспечения или в адрес перехода. Вставка "заплат" в MS-DOS через векторы прерываний программного обеспечения обычно не делается потому, что в операционной системе MS-DOS отсутствует возможность распознавания таблицы переходов. Кроме того, в связи с тем, что не существует стандартный интерфейс между MS-DOS и интерфейсом ее BIOS, вставка "заплат" между MS-DOS и BIOS обычно затруднительна. Использование прерываний программного обеспечения остается проблематичным.


Одним из общих мест вставки "заплат" в векторы прерываний MS-DOS является прерывание int 28h. Это, по-видимому, вспомогательное прерывание, используемое внутри MS-DOS. Это также одна из точек вставки "заплат", в которую гарантируется частый доступ. Резидентная подпрограмма, вставленная в качестве "заплаты" в этой точке, не может вызывать драйверы функций MS-DOS, т.к. это приведет к сбою системы. Резидентная подпрограмма также должна использовать свой собственный контекст для предотвращения изменения существующего стека и регистров. Листинг 3-12 показывает программные коды, необходимые для установки резидентной подпрограммы в прерывании int 28h и поддержки этой резидентной подпрограммы.



           Листинг 3-12. Программа INIT28 - Вставка "заплат" в векторы
                                прерываний системы
         ----------------------------------------------------------------

         ; ==== INIT28 - Этот файл вырабатывает программу формата .COM ==
         ; ==== Установка резидентной подпрограммы путем вставки ========
         ; ==== "заплаты" в прерывание int 28h ==========================
         PAGE    60,132
         ; ==== Соответствует установке прерывания ======================
         VECT_NUM EQU    28h          ; номер вектора для установки
         OFF     EQU     0h           ; подпрограмма неактивна
         ON      EQU     0FFFFh       ; подпрограмма активна
         ;
         INCLUDE STDMAC.INC          ; включение описания макробиблиотеки
         ; ==== НАЧАЛО ПРОГРАММНОЙ СЕКЦИИ ===============================
         init28  SEGMENT
                 ASSUME  cs:init28
                 ASSUME  ds:init28
                 ORG     0
         SEG_ORG EQU     $
                 ORG     0100h
         main    PROC    FAR
         start:  jmp     init         ; пропуск памяти "старого вектора"
         old_v   dd      ? ; пространство для запоминания старого вектора
         entry:  jmp     first        ; пропуск "идентификации"
                 db      'TEST ROUTINE'
         first:  @SwapNewStack     ; макрос для переключения в новый стек
                 cmp     go_switch,ON ; проверка если я активна
                 jne     bypass       ; да - продолжить для выхода
                 mov     go_switch,OFF ; нет - установка переключателя
                                       ; активна
         ;
         ;  < ЗДЕСЬ ИДЕТ ВАША РЕЗИДЕНТНАЯ ПОДПРОГРАММА >
         ;
                 mov     go_switch,ON ; установка состояния неактивна
         bypass: @SwapOLDStack    ; установка стека (и включение данных)
                 jmp     cs:exit  ; переход к подпр-ме обслуж-я прерыв-я
         exit            dd     ?
         go_switch       dw     ?
                         db     32 dup ('stack   ')
         TOS             EQU    $
         LAST_BYTE       EQU    $
         ;
         ; ===== СЕКЦИЯ ИНИЦИАЛИЗАЦИИ - ПОСЛЕ ЗАГРУЗКИ НЕ НУЖНА =========
         ;
         init:   mov     go_switch,OFF ; предупреждение активизации
                 mov     ah,35h        ; получение адреса вектора
                 mov     al,VECT_NUM
                 @DosCall
                 mov     word ptr exit,bx ; сохранение указателя IP для
                                          ; выхода
                 mov     word ptr exit+2,es ; сохранение указателя CS для
                                            ; выхода
                 mov     word ptr old_v,bx  ; сохранение указателя IP для
                                            ; удаления
                 mov     word ptr old_v+2,es ; сохранение указателя CS
                                             ; для удаления
                 mov     ah,25h         ; установка нового указателя
                 mov     al,VECT_NUM
                 mov     dx,offset entry ; установка указателя IP
                                         ; ... (CS и DS аналогично)
                 @DosCall
                 mov     go_switch,ON
                 mov     dx,9offset LAST_BYTE - SEG_ORG + 15) shr 4
                 mov     ah,31h   ; завершить и оставить резидентной
                 @DosCall
         ;
         main    ENDP
         init28  ENDS
                 END     start
         ----------------------------------------------------------------

Другие возможные точки вставки "заплат" зависят от типа резидентной подпрограммы и частоты, с которой она должна вызываться. Например, подпрограмма буферизации печати - print spooler routine (которая печатает файлы во время выполнения других программ) не только должна прерывать прерывание для активации передачи символов в принтер, но также должна прерывать любое обращение к MS-DOS, которое использует принтер, так, чтобы не возникали конфликты. Рис.3-16 показывает прерывание буферизации печати int 28h для активации самой себя и прерывание int 21h для охраны самой себя от конфликтов при доступе к принтеру.



                                  ---------------
                прерывание       |     ...       |  Таблица векторов се-
            ---------------------| Int 21 IP/CS  |<---------------------
           |    прерывание       |     ...       |  мейства микропроцес-|
           |  -------------------| Int 28 IP/CS  |<-----    соров 8086  |
           | |                   |     ...       |      |               |
           | |                    ---------------       |Внешний вызов  |
           | |                    ---------------       |   Int 28h     |
           | |            ------>|    MS-DOS     |------     MS-DOS     |
           | |           |       |     ...       |                      |
           | |   --------|-------|  Коды Int 21  |<-----------------    |
           | |  |        |       |     ...       |                  |   |
           | |  |         -------|  Коды Int 28  |<------- Возврат  |   |
           | |  |                 ---------------        |    в     |   |
           | |  |                 ---------------        | MS-DOS   |   |
           |  --|--------------->| Подпрограмма  |       | из пре-  |   |
           |    |                |  буферизации  |       | рывания  |   |
           |    |                |     ...       |       | Int 21h  |   |
           |    |                |  Коды печати  |-------           |   |
           |    |                |     ...       |                  |   |
           |    |                |---------------|Передача Int 21h  |   |
            ----|--------------->|Проверка Int 21|------------------    |
                |                 ---------------                       |
                |                 ---------------                       |
                |                |   Программа   |                      |
                |                |  пользователя |                      |
                |                |     ...       |                      |
                 --------------->| Int 21h |----------------------------
            Возврат Int 21 в     |     ...       |
            программе пользова-   ---------------
                   теля

            Рис.3-16. Использование векторов прерываний подпрограммой
                                буферизации печати

При любом использовании векторов прерываний для реализации некоторого подобия параллелизма, имеется риск "выхода" из выполнения программы, осуществляющей непосредственный доступ к аппаратным средствам. Например, если для обеспечения некоторых возможностей устанавливается вектор прерывания клавиатуры и если другая программа обходит вектор клавиатуры и вместо этого осуществляет чтение с аппаратных средств, то резидентная подпрограмма не получает управления. Этот эффект может легко произойти, если устанавливается несколько резидентных программ, потому что каждая программа должна обойти MS-DOS для выполнения ввода/вывода. Например, если и подпрограмма буферизации печати и резидентная подпрограмма устанавливаются для печати содержимого видеодисплея, и обе активизированы в одно и тоже время, то произойдет конфликт. Эти проблемы могут также возникнуть и при установке имеющихся в наличии коммерческих резидентных подпрограмм. У пользователей существует только один способ защитить себя - это установка только одной подпрограммы для проверки конфликтов.


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

Hosted by uCoz