Вы сможете использовать обычную программу DEBUG для отладки тес-
товой программы и самого драйвера. Это позволит Вам довести драй-
вер до состояния, при котором он уже может быть загружен, после
чего использовать другие способы отладки для исправления остав-
шихся ошибок.
При разработке драйверов всегда пользуйтесь копией системного
диска. Ошибка в драйвере может привести к тому, что система не
будет загружаться или к разрушению каких-либо значимых данных на
диске. По этим причинам Вам следует всегда иметь копию системного
диска.
Отображение списка загруженных в системе драйверов
Очень часто при отладке драйверов полезно знать какие конкрет-
но драйверы загружены в данный момент. На этот случай мы приводим
текст небольшой программы, названной SD (SHOW DRIVERS - показать
драйверы). Примерный вид выводимой этой программой информации по-
казан в листинге 6-5.
Большинство отображаемых драйверов являются стандартными драй-
верами MS-DOS, эа исключением верхнего драйвера CON-устройства
(драйвера консоли), который является драйвером ANSYI.SYS, и верх-
него блокового драйвера, который является Bernulli Box драйвером.
Нижний блоковый драйвер является стандартным MS-DOS драйвером,
поддерживающем одновременно один жесткий диск и два гибких.
Колонка Attrib содержит слова атрибутов драйверов, колонка
Address содержит начальный адрес каждого драйвера (взятый из поля
связи предыдущего в списке драйвера) и колонки STRAT и INTRP со-
держат смещения программ СТРАТЕГИЙ и ПРЕРЫВАНИЙ от начала драйве-
ра. Исходный текст программы SD на языке ассемблера приведен в
листинге 6-6. Заметьте, что в программе SD используются файлы
DRIVER.INC (листинг 6-7), STDMAC.INC (листинг A-7, приложение A)
и программа BIN2HEX файла STDLIB.LIB (листинг A-8, приложение A).
- 6-49 -
Листинг 6-5. Пример цепочки драйверов, выводимый программой SD
--------------------------------------------------------------------
SD-ShowDriv, Version 1.00, Copyright 1988 Kevin Jaeger
Device Type Units Attrib Address STRAT INTRP
-------------------------------------------------------------------
NUL Char 01 8004 0000:1898 1418 141E
CON Char 01 8013 08A9:0000 00A2 00AD
-------- Block 02 0000 083D:0000 00A7 00B2
CON Char 01 8013 0070:0160 00A7 00B2
AUX Char 01 8000 0070:01F1 00A7 00B8
PRN Char 01 A000 0070:02A0 00A7 00C7
CLOCK$ Char 01 8008 0070:034A 00A7 00DC
-------- Block 03 0800 0870:0416 00A7 00E2
COM1 Char 01 8000 0070:0203 00A7 00B8
LPT1 Char 01 A000 0070:02B2 00A7 00C7
LPT2 Char 01 A000 0070:0B13 00A7 00CD
LPT3 Char 01 A000 0070:0B25 00A7 00D3
COM2 Char 01 8000 0070:0B37 00A7 00BE
<<< ------------------ End Of Driver List --------------------- >>>
--------------------------------------------------------------------
Листинг 6-6. Исходный текст программы SHOWDRIV.ASM
---------------------------------------------------------------------
PAGE 60,132
; ************ SHOWDRIV *********************************************
;
; SHOWDRIV - Отображение списка загруженных драйверов MS-DOS
;
; ************ INCLUDES *********************************************
;
INCLUDE stdmac.inc
INCLUDE driver.inc
;
; ************ DGROUP (DATA) COMPONENT SEGMENTS *********************
;
_DATA SEGMENT BYTE PUBLIC 'DATA'
_DATA ENDS
;
STACK SEGMENT PARA STACK
dw 1024 dup (?)
STACK ENDS
;
DGROUP GROUP _DATA, STACK
;
; ************ DATA STORAGE & TEMPLATES *****************************
;
_DATA SEGMENT BYTE PUBLIC 'data'
;
; параметры для поиска
;
nuldev db 'NUL ' ; Имя NUL драйвера
nulattr dw AT_CHR OR AT_NUL ; Слово атрибутов
;
; Текстовые сообщения для вывода на дисплей. Формат :
;
; "Device Type Units Attrib Address STRAT INTRP"
; "-----------------------------------------------------------------"
; "xxxxxxxx xxxx xx xxxx xxxx:xxxx xxxx xxxx"
- 6-50 -
; "<<< ------------------ End Of Driver List ------------------- >>>"
;
$title db CR,LF
db 'SD-ShowDriv, Version 1.00, Copyright 1988'
db CR,LF,CR,LF
db 'Device Type Units Attrib Address'
db ' STRAT INTRP'
db CR,LF
db '-----------------------------------------------'
db '--------------------'
db CR,LF,'$'
$space db ' $'
$block db '-------- Block $'
$char db 'Char$'
$colon db ':'
$end db CR,LF
db '<<< ------------------ End Of Driver List -----'
db '---------------- >>>'
$crlf db CR,LF,'$'
;
; Шаблон структуры
;
devhead STRUC ; Структура заголовка драйвера
next dd ? ; Указатель на следующего...
attrib dw ? ; Слово атрибутов
strat dw ? ; Смещение программы СТРАТЕГИЙ
intrp dw ? ; Смещение программы ПРЕРЫВАНИЙ
dname db 8 dup (?) ; Имя/количество устройств
term db ? ; Конец заголовка драйвера
devhead ENDS
;
_DATA ENDS
;
; ************ ПРОГРАММА НАЧИНАЕТСЯ ЗДЕСЬ ***************************
;
_TEXT SEGMENT BYTE PUBLIC 'CODE'
ASSUME cs:_TEXT, ds:DGROUP, es:DGROUP, ss:DGROUP
;
EXTRN bin2hex:near ; Шестнадцатиричный вывод
main PROC FAR
mov ax,DGROUP ; Установка сегмента данных
mov ds,ax
; Найдем NUL-драйвер с помощью поиска имени "NUL"
;
cld
mov cx,0FFFEh ; Счетчик для поиска
xor ax,ax ;
mov es,ax ; Начало поиска после таблицы
mov di,0400h ; прерываний
mov al,nuldev[rv] ; Начинаем с поиска этой буквы
;; mov al,[nuldev[rv]
search:
repne scasb ; Ищем пока не найдем
jne exit ; Не нашли...
;
push cx ; Возможно нашли...
push di ; Сохраним текущую позицию
- 6-51 -
mov si,offset nuldev+1 ; Остаток строки "NUL "
mov cx,7 ; Длина остатка
repe cmpsb ; Сравним остаток строки
jne not_it ; Не совпадают...
;
sub di,(offset term - offset attrib) ; Выровняем указатель
cmpsw ; Это атрибут NUL-драйвера ?
jne not_it ; Нет...
add sp,4 ; Удаляем сохраненные DI и CX
sub di,(offset strat - offset next) ; Выравниваем указатель
jmp found_nul ; Нашли заголовок NUL-драйвера!
;
not_it: ; Восстанавливаем позицию
pop di ; и счетчик
pop cx
jmp short search
;
; Нашли заголовок NUL-драйвера. Теперь выводим всю цепочку
;
found_nul:
@DisStr $title ; Выводим название (титул)
show_driver:
call ShowDeviceInfo ; Отобразим заголовок драйвера
cmp word ptr es:[di],-1 ; Проверим на конец цепочки
je done ; Если (-1) то на выход
les di,es:[di.next] ; Если не (-1) то на следующий
jmp short show_driver ; заголовок
done:
@DisStr $end ; Завершающее сообщение
@DisStr $crlf
;
exit: mov al,0 ; Нормальное завершение
@ExitToDOS ; Завершение программы
main ENDP
;
; ************ ShowDeviceInfo ****************************************
; Подпрограмма ShowDeviceInfo отображает блок, адресуемый по ES:DI,
; предполагая что это заголовок драйвера. Формат выводимой информации
; показан выше.
;
ShowDeviceInfo PROC NEAR
test es,[di.attrib],AT_CHR ; Драйвер символьный или
jnz is_char ; блоковый ?
@DisStr $block ; Блоковый (без имени)
xor ah,ah
mov al,es:[di.dname] ; Количество устройств
jmp short dis_units
is_char:
push ds ; Сохраним DS
push es ; Выровняем сегменты
pop ds
lea si,es:[di.dname] ; SI = смещение имени
mov cx,8 ; Длина имени
show_name:
lodsb ; Выводим по одному символу
@DisChr al ; за раз
loop show_name
- 6-52 -
pop ds ; Восстанавливаем DS
@DisStr $space
@DisStr $char ; Выводим тип драйвера
@DisStr $space
mov ax,1 ; Только одно устройство
;
dis_units:
mov ch,02 ; Выводим количество устройств
call bin2hex
@DisStr $space
mov ch,04 ; Вывод числовых данных
mov ax,es:[di.attrib]
call bin2hex ; Выводим слово атрибутов
@DisStr $space
;
mov ax,es
call bin2hex ; Выводим сегментный адрес
@DisChr $colon
mov ax,di
call bin2hex ; Выводим смещение
@DisStr $space
;
mov ax,es:[di.strat]
call bin2hex ; Выводим адрес СТРАТЕГИЙ
@DisStr $space
;
mov ax,es:[di.intrp]
call bin2hex ; Выводим адрес ПРЕРЫВАНИЙ
@DisStr $crlf
;
ret
ShowDeviceInfo ENDP
;
; ************ КОНЕЦ ПРОГРАММЫ, КОНЕЦ ФАЙЛА ************************
;
_TEXT ENDS
END main
---------------------------------------------------------------------
Листинг 6-7. Файл DRIVER.INC