Поле 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
Функция 32H принимает в регистр DL номер устройства (0 - текущий диск, 1 - А: и т.д.) и возвращает в регистрах DS:BX адрес соответствующего блока DDCB. Если номер устройства был задан неправильно, регистр AL после выполнения функции будет содержать значение FF.
Также можете проверить мою программу на своем устройстве (не забудьте установить во все дисководы по диску ). Если дисков много, то следует перенаправить вывод из программы в файл (prog.com > file.txt).
Была использована версия компилятора MASM 6.11 в контексте операционной системы MS DOS 6.22!
Спасибо за внимание!
С уважением, push0ret!