Управлять дисками можно как через порты ввода/вывода, так и через BIOS. Порты намного более могущественны и интересны, однако BIOS программируется намного проще, к тому же она поддерживает большое количество разнокалиберных накопителей, абстрагируясь от конструктивных особенностей каждой конкретной модели. Поэтому будем действовать через нее, а точнее, через интерфейс прерывания
INT 13h
.
Попробуем прочитать сектор с диска в режиме CHS. Действовать нужно из самой MBR или из "голой" MS-DOS, иначе у нас ничего не получится, ведь Windows NT блокирует прямой доступ к диску даже из режима эмуляции MS-DOS.
Номер функции заносится в регистр
AH
.
В случае чтения он равен двум. Регистр
AL
отвечает за количество обрабатываемых секторов. Так как мы собираемся читать по одному сектору за операцию, занесем сюда единицу. Регистр
DH
хранит номер головки, a
DL
— номер привода (
80h
— первый жесткий диск,
81h
— второй и т.д.). Пять младших битов регистра
CL
задают номер сектора, оставшиеся биты регистра
CL
и восемь битов регистра
CH
определяют номер цилиндра, который мы хотим прочитать. Регистровая пара
ES:BX
указывает на адрес буфера-приемника. Вот, собственно говоря, и все. После выполнения команды
INT 13h
считываемые данные окажутся в буфере, а если произойдет ошибка (например, головка "споткнется" о BAD-сектор), то BIOS установит флаг переноса (carry flag), и мы будем вынуждены либо повторить попытку, либо вывести грустное сообщение на экран.
Код этой программы на языке ассемблера представлен в листинге 5.6.
Листинг 5.6. Код, считывающий загрузочный сектор или расширенную таблицу разделов
MOV SI, 1BEh ; Перейти к первому разделу
MOV AX, CS ; Настраиваем ES
MOV ES, AX
MOV BX, buf ; Смещение буфера
...
read_all_partitions:
MOV AX, bud ; Читать 1 сектор с диска
MOV DL, 80h ; Читать с первого диска
MOV DH, [SI+1] ; Стартовый номер головки
MOV CX, [SI+2] ; Стартовый сектор с цилиндром INT 13h
JC error ; Ошибка чтения
;Обрабатываем считанный boot-сектор или расширенную таблицу разделов