Библиотека DLL для драйвера
При написании приложений в системе Windows обычно в программном модуле имеют дело только с двумя типами сегментов: перемещаемым (moveable) и выгружаемым (discardable). Сегменты данных программы являются перемещаемыми, т.е. их линейные адреса в памяти могут изменяться, когда программе управления памятью системы Windows требуется организовать память. Селектор (selector) и смещение, используемые для доступа к определенной ячейке памяти, остаются фиксированными, но под схемой селектор-смещение система Windows может перемещать фактические данные в линейной памяти.
Сегменты программ-кодов также перемещаемые, но имеют дополнительный атрибут - выгружаемые. Их содержимое может быть выгружено полностью, а при необходимости загружено с диска, так как нельзя писать и (или) модифицировать информацию в сегменте программы-кода. Если при обращении к сегменту из программы Windows, он оказался выгруженным, программа управления памятью системы Windows автоматически обратится к диску и прочитает ранее выгруженный сегмент.
Итак, каким образом это обстоятельство влияет на код для программы ISR? Так как прерывание может произойти в любое время, а код ISR может оказаться выгруженным, то возникнет проблема загрузить код в память, если фиксируется прерывание. Вместо этого, можно описать сегмент как FIXED (фиксированный), а не как MOVEABLE (перемещаемый) или DISCARDABLE (выгружаемый). Сегмент с атрибутом FIXED будет оставаться в единственном месте линейной памяти и не будет выгружаться, даже если он содержит код. В этом случае, если произойдет прерывание, код будет доступен и готов к выполнению. Однако следует отметить один малоизвестный факт, а именно: в системе Windows только те сегменты будут считаться FIXED, которые были описаны в библиотеке DLL. Сегмент FIXED в обычном программном модуле будет рассматриваться как MOVEABLE. Таким образом в системе Windows нельзя будет поместить программу ISR в обычный программный модуль. Вместо этого ее необходимо поместить в библиотеку DLL.
Листинг 2 представляет исходный код bogusa.asm на ассемблере для библиотеки DLL, который содержит программу ISR и может выполняться в окружении Windows. Программа IntSvcRtn очень похожа на свой дубликат, работающий в системе MS-DOS. Однако кроме увеличения переменной-счетчика данная программа ISR также записывает в очередь сообщение Windows. Чтобы избежать переполнения очереди, запись сообщения производится только в случае, когда переменная-счетчик wCount изменяет значение от 0 к 1. Функция обнуления счетчика wCount после того, как закончена обработка сообщения, передана высокоуровневой программе системы Windows.
С первого взгляда все эти рассуждения кажутся простыми, однако обработка прерываний в системе Windows совсем не так проста, как в системе MS-DOS.
page ,132
; masm tisr ; >err
.286p
.xlist
include bogus.inc
include pic.h
.list
WM_COMMAND=0111h
EXTRN POSTMESSAGE:FAR
Words struc
LoWord dw ?
HiWord dw ?
Words ends
;
; Установить переменные для нашего номера прерывания
;
ife (FAKE_IRQ GE 8)
INT_DEV equ (INT_MASTER_0+(FAKE_IRQ AND 7))
PIC00 equ INTA00
PIC01 equ INTA01
else
INT_DEV equ (INT_SLAVE_0+(FAKE_IRQ AND 7))
INT_MASK equ 1 SHL (FAKE_IRQ AND 7))
PIC00 equ INTB00
PIC01 equ INTB01
endif
FIXED_DATA SEGMENT DWORD PUBLIC 'DATA'
PUBLIC _hWndEvent,_wParamEvent,_wCount
_hWndEvent label word
hWndEvent dw 0 ; Окно для постирования событий
_wParamEvent label word
wParamEvent dw 0 ; Значение wParam для постирования
_wCount label word
wCount dw 0 ; Счетчик необработанных прерываний
FIXED_DATA ENDS
; IP IntSvcRtn - программа обслуживания прерываний
;
; WARNINGS (Предупреждения)
;
; NOTES (Примечания)
; Данная программа ISR увеличивает счетчик прерываний и заново
; маскирует устройство.
; Если предыдущее значение счетчика было равно 0, то записывается
; сообщение
; Если установлен флаг "fStopping", устройство не маскируется заново.
;
FIXED_TEXT SEGMENT PARA PUBLIC 'CODE'
selData1 dw FIXED_DATA
assume CS:FIXED_TEXT,DS:NOTHING
PUBLIC _IntSvcRtn
_IntSvcRtn label far
IntSvcRtn proc far
push ax
push dx
push ds
mov ds,selDatal
assume ds:FIXED_DATA
inc wCount
mov al,NOT FAKE_CTL_EOI
mov dx,FAKE_PORT
out dx,al ; посылаем устройству EOI
mov al,EOI
out PIC00,al ; посылаем EOI контроллеру PIC
ife (PIC00 EQ INTA00)
out INTA00,al ; посылаем EOI также главному контроллеру PIC
endif
cmp hWndEvent,0 ; завершать?
jz isr9 ; если да, то не делаем перезапуска и
; постирования
cmp wCount,1 ; требуется постирование?
jne isr8 ; пропускаем, если нет
push bx ; сохраняем оставшиеся регистры
push cx
push es
push hWndEvent
push WM_COMMAND
push wParamEvent
push 0 ; lParam равно 0
push 0
call POSTMESSAGE ; регистрируем событие
pop es
pop cx
pop bx
isr8:
mov al,NOT FAKE_CTL_START
mov dx,FAKE_PORT
out dx,al ; возобновляем ввод-вывод
isr9:
pop ds
assume ds:NOTHING
pop dx
pop ax
iret
IntSvcRtn endp
; требуется программе AllocIntReflector
PUBLIC _BogusCallback
_BogusCallback label far
BogusCallback proc far
pushf
call IntSvcRtn
ret
BogusCallback endp
FIXED_TEXT ENDS
end
; конец файла
_____________________________________________________________________
Листинг 2. Программа bogusa.asm
Дата добавления: 2016-04-06; просмотров: 541;