Список управляющих блоков устройств (DDCB)

Ответить
Аватара пользователя
push0ret
Сообщения: 7
Зарегистрирован: Вс дек 29, 2024 2:48 pm
Поблагодарили: 7 раз
Контактная информация:

Список управляющих блоков устройств (DDCB)

Сообщение push0ret »

Hello, world!

Поле dev_cb в векторной таблице связи MS DOS (структура векторной таблицы связи в этой теме: viewtopic.php?t=97) содержит дальний адрес цепочки блоков управления устройствами (DOS Device Control Block - DDCB). Такая структура строится для каждого дискового устройства, подключенного к компьютеру под управлением операционной системы MS DOS. Блок DDCB для каждого устройства содержит информацию о характеристиках дискового устройства и адрес заголовка драйвера устройства.

Эта структура используется программами, которые осуществляют доступ к диску (чтобы в полной мере понимать значение каждого поля структуры рекомендуется знать как устроена файловая система)

Приведу формат блока DDCB:

(0) db drv_num номер устройства (0 соответствует устройству А:, 1 - В: и т.д.)
(+1) db drv_numd дополнительный номер устройства внутри драйвера
(+2) dw sec_size размер сектора в байтах
(+4) db clu_size число, на единицу меньшее количества секторов в кластере
(+5) db clu_base если содержимое этого поля не равно нулю, то для получения общего числа секторов в кластере надо возвести 2 в степень clu_base и получившееся число прибавить к clu_size
(+6) dw boot_siz количество зарезервированных секторов (boot-сектора, начало корневого каталога)
(+8) db fat_num количество копий FAT
(+9) dw max_dir максимальное число дескрипторов файлов в корневом каталоге (т.е. максимальное число файлов, которое может содержать корневой каталог на этом устройстве)
(+11)dw data_sec номер первого сектора данных на диске (номер сектора, соответствующего кластеру номер 2)
(+13)dw hi_clust максимальное количество кластеров (равно увеличенному на 1 количеству кластеров данных)
(+15)db fat_size количество секторов, занимаемых одной копией FAT
(+16)dw root_sec номер первого сектора корневого каталога
(+18)dd drv_addr FAR-адрес заголовка драйвера, обслуживающего данное устройство
(+22)db media байт описания среды носителя данных
(+23)db acc_flag флаг доступа, 0 означает, что к устройству был доступ
(+24)dd next адрес следующего блока DDCB, для последнего блока в поле смещения находится число FFFF
--------------- только для DOS 2.x -----------------
(+28)dw dir_clu номер начального кластера текущего каталога (0 для корневого каталога)
(+30)64 dir_path строка в формате ASCIIZ, содержащая путь к текущему каталогу
----- DOS 3.х ------
(+28) 2 reserv1 зарезервировано, обычно равно 0
(+30) 2 built число FFFF в этом поле означает, что блок DDCB был построен

Формат блока DDCB для DOS 4.x:

(0) db drv_num номер устройства (0 соответствует устройству А:, 1 - В: и т.д.)
(+1)db drv_numd дополнительный номер устройства внутри драйвера
(+2)dw sec_size размер сектора в байтах
(+4)db clu_size число, на единицу меньшее количества секторов в кластере
(+5)db clu_base если содержимое этого поля не равно нулю, то для получения общего числа секторов в кластере надо возвести 2 в степень clu_base и получившееся число прибавить к clu_size
(+6)dw boot_siz количество зарезервированных секторов (boot-сектора, начало корневого каталога)
(+8)db fat_num количество копий FAT
(+9)dw max_dir максимальное число дескрипторов файлов в корневом каталоге (т.е. максимальное число файлов, которое может содержать корневой каталог на этом устройстве)
(+11)dw data_sec номер первого сектора данных на диске (номер сектора, соответствующего кластеру номер 2)
(+13)dw hi_clust максимальное количество кластеров (равно увеличенному на 1 количеству кластеров данных)
(+15)db fat_size количество секторов, занимаемых одной копией FAT
(+16)db reserv1 зарезервироано
(+17)dw root_sec номер первого сектора корневого каталога
(+19)dd drv_addr FAR-адрес заголовка драйвера, обслуживающего данное устройство
(+23)db media байт описания среды носителя данных
(+24)db acc_flag флаг доступа, 0 означает, что к устройству был доступ
(+25)dd next адрес следующего блока DDCB, для последнего блока в поле смещения находится число FFFF
(+29)dw reserv2 зарезервироано
(+31)dw built число FFFF в этом поле означает, что блок DDCB был построен

Замечу, что формат этой структуры не описан в документации MS DOS, он может отличаться в разных версиях, я использую версию MS DOS 6.22.

Теперь напишу программу, которая отображает некоторые поля всех DDCB в системе:

Код: Выделить всё

.model	tiny
.286
code	segment
org	100h

;Which DDCB fields are most important for determining the characteristics
;of a disk devise and why?

;drv_num and sec_size for get access for devise with number of drive
;and know the sector size to understand how to access the desired areas
;of this device.

start:

;Get first DDCB address

mov ah, 52h
int 21h

mov ax, word ptr es:[bx]
mov dx, word ptr es:[bx+2]

mov ddcb_off, ax
mov ddcb_seg, dx

;Get and translate values of fields of structure for display

mov es, dx
mov bx, ax

scan_ddcb:

;Get drv_num

xor ax, ax
mov al, byte ptr es:[bx]

push ax
push offset display.drv_num+1
call hex_dec

;Get sector size

push word ptr es:[bx+2]
push offset display.sec_size+3
call hex_dec 

;Get count of fat

xor ax, ax
mov al, byte ptr es:[bx+8]

push ax
push offset display.fat_num+1
call hex_dec

;Get number of maximum files in root directory

push word ptr es:[bx+9]
push offset display.max_dir+3
call hex_dec

;Get driver address

push word ptr es:[bx+19]
push offset display.drv_addr+8
call hex_ascii

push word ptr es:[bx+21]
push offset display.drv_addr+3
call hex_ascii

mov ah, 9d
mov dx, offset display
int 21h

;Last DDCB or no?

cmp word ptr es:[bx+25], 0FFFFh
jz exit

;Get next DDCB address

push es
push bx
call next

inc display.msg0

jmp scan_ddcb

exit:

mov ax, 4c00h
int 21h

ddcb_off	dw	?
ddcb_seg	dw	?

display_	struc

msg0		db	30h, ' DDCB:', 0Ah, 0Dh
msg1		db	'Device number:  ', 9d
drv_num		db	0, 30h, 0Ah, 0Dh
msg2		db	'Sector size:    ', 9d
sec_size	db	4d dup(0), ' bytes', 0Ah, 0Dh
msg3		db	'Count of FAT:   ', 9d
fat_num		db	2d dup(0), 0Ah, 0Dh
msg4		db	'Max descriptors:', 9d
max_dir		db	4d dup(0), ' Files', 0Ah, 0Dh
msg5		db	'Driver address: ', 9d
drv_addr	db	4d dup(0), ':', 4d dup(0)
return		db	0Ah, 0Ah, 0Dh, 24h

display_	ends

display	display_	<>

;GET NEXT DDCB PROCEDURE.
;PARAMETERS(STACK):
;- SEGMENT OF DDCB
;- OFFSET OF DDCB
;OUT:
;ES:BX = ADDRESS OF NEXT DDCB
;OR ES:BX = ADDRESS CURRENT DDCB IF DDCB LAST

next		proc	uses bp dx ax

mov bp, sp

mov bx, word ptr ss:[bp+8]
mov ax, word ptr ss:[bp+10]
mov es, ax

cmp word ptr es:[bx+25], 0FFFFh
jz last

mov ax, word ptr es:[bx+25]		;Offset of next DDCB
mov dx, word ptr es:[bx+27]		;Segment of next DDCB

mov es, dx
mov bx, ax

last:

ret 4

next		endp

;------------------------------------------
;HEX IN DECIMAL ASCII PROCEDURE.
;PARAMETERS(STACK):
;- NUMBER
;- LAST BYTE IN ARRRAY FOR DISPLAY

hex_dec		proc	uses bp dx bx ax di

mov bp, sp
mov di, word ptr ss:[bp+12]
mov ax, word ptr ss:[bp+14]
mov bx, 0Ah
xor dx, dx

write_dec:

cmp ax, 0
jz stop_dec

div bx
add dl, 30h
mov byte ptr[di], dl
dec di
xor dx, dx
jmp write_dec

stop_dec:

ret 4

hex_dec		endp

;------------------------------------------
;HEX IN ASCII PROCEDURE.
;PARAMETERS(STACK):
;- NUMBER
;- LAST BYTE IN ARRAY FOR DISPLAY

hex_ascii	proc	uses ax bx di cx bp

mov bp, sp
mov di, word ptr ss:[bp+12]
mov bx, word ptr ss:[bp+14]
mov cx, 4d

translate:

mov ax, bx
and ax, 0Fh

cmp al, 9d
ja letter

add al, 30h
mov byte ptr[di], al
ror bx, 4d
dec di
loop translate

jmp end_of_trans

letter:

add al, 37h
mov byte ptr[di], al
ror bx, 4d
dec di
loop translate

end_of_trans:

ret 4

hex_ascii	endp

code	ends
end	start
Приведенный выше способ получения доступа к блокам DDCB подходит для просмотра блоков управления всеми дисковыми устройствами. Если необходимо получить структуру DDCB для какого-нибудь конкретного устройства, можно воспользоваться недокументированной функцией 32H прерывания INT 21H.

Функция 32H принимает в регистр DL номер устройства (0 - текущий диск, 1 - А: и т.д.) и возвращает в регистрах DS:BX адрес соответствующего блока DDCB. Если номер устройства был задан неправильно, регистр AL после выполнения функции будет содержать значение FF.

Также можете проверить мою программу на своем устройстве (не забудьте установить во все дисководы по диску ;)). Если дисков много, то следует перенаправить вывод из программы в файл (prog.com > file.txt).

Была использована версия компилятора MASM 6.11 в контексте операционной системы MS DOS 6.22!

Спасибо за внимание!
С уважением, push0ret!
Ответить

Вернуться в «Системное программирование»