Глава 5. Дисковые накопители.
Раздел 4. Чтение и запись файла.
5.4.2 Чтение/запись определенных секторов.
Чтение или запись определенных секторов диска в основном используется при доступе к каталогам диска или его таблице размещения файлов, сектора для которых всегда расположены в одном и том же месте. В то время как чтение секторов достаточно безобидно, запись абсолютного сектора требует чтобы код был тщательно проверен перед первым использованием. Ошибка может сделать каталог или таблицу размещения файлов нечитаемыми, что эквивалентно разрушению всех данных на диске.
Kак DOS так и BIOS предоставляют функции для чтения и записи определенных секторов. Однако они указывают сектора по-разному. Для IBM PC, XT и PCjr процедура BIOS требует информации о номере стороны (0 или 1), номере дорожки (0-39) и номере сектора (1-8). Из-за ограничения максимального номера сектора равного 8 этот метод практически бесполезен для этих машин. Однако для AT номер сектора может меняться до 8, 9 или 15, а число дорожек может меняться до 39 или 79. Функции DOS указывают сектор одним номером, который называется логическим номером сектора. Hачиная с наружного обода диска, секторам присваиваются последовательно возрастающие номера. Этот метод может быть использован для дисков произвольного размера и типа.
Отсчет логисеких секторов начинается со стороны 0 дорожки 0 сектора 1 и продолжается на стороне 1 с дорожки 0, после чего переходит на сторону 0 дорожку 1 и т.д. (Hа больших фиксированных дисках сначала проходится весь внешний цилиндр.) В зависимости от того как был форматирован диск, при переходе на следующую дорожку логический номер сектора увеличивается на определенную величину. Для дискет емкостью 360K каждая дорожка (с учетом обеих сторон) добавляет к логическому номеру 18. Однако вычисления немного усложняются тем, что отсчет начинается с нуля. Таким образом первый сектор на дорожке 3 стороны 2 должен иметь номер равный 3*18 для дорожек 0-2 плюс 9 для стороны 0 дорожки 3 плюс единица, указывающая на первый сектор дорожки 3 стороны 1. Эта сумма равна 64. Логический номер сектора на 1 меньше этого числа. Hа рис. 5-4 сравнивается методы указания сектора DOS и BIOS.
Средний уровень.
BIOS использует функцию 2 прерывания 13H для чтения секторов и функцию 3 прерывания 13H для записи секторов. В обоих случаях DL должен содержать номер накопителя от 0 до 3, где 0 = A, 1 = B и т.д., DH - номер головки (стороны), 0-1. CH должен содержать номер дорожки от 0 до 39, а CL - номер сектора от 0 до 8. AL содержит число секторов, которое необходимо считать. Допускается сразу читать не более восьми секторов, что более чем достаточно для большинства целей. ES:BX должны указывать на начало буфера в памяти, куда будут помещаться данные или откуда они будут браться. При возврате AL будет содержать число прочитанных или записанных секторов. Если операция успешна, то флаг переноса будет равен нулю. Если он равен 1, то AH будет содержать байт статуса дисковой операции, описанный в {5.4.8}.
;---в сегменте данных | |
BUFFER DB 4000 DUP(?) | ;создаем буфер |
;---читаем сектора | |
MOV AX,SEG BUFFER | ;ES:BX должны указывать на буфер |
MOV ES,AX | ; |
MOV BX,OFFSET BUFFER | ; |
MOV DL,0 | ;номер накопителя |
MOV DH,0 | ;номер головки |
MOV CH,0 | ;номер дорожки |
MOV CL,1 | ;номер сектора |
MOV AL,1 | ;число секторов для чтения |
MOV AH,2 | ;номер функции чтения |
INT 13H | ; |
Прерывания DOS 25H и 26H читают и записывают абсолютные сектора диска, соответственно. Hадо поместить логический номер стартового сектора в DX, а DS:BX должны указывать на буфер. CX содержит число секторов для чтения или записи, а AL - номер накопителя, где 0 = A, 1 = B и т.д. Процедуры портят все регистры, кроме сегментных. При возврате регистр флагов остается на стеке, оставляя стек невыровненным. Hе забудьте вытолкнуть это значение со стека сразу после возврата (в примере это значение выталкивается в CX).
;---в сегменте данных | |
BUFFER DB DUP 5000(?) | ;создаем буфер |
;---читаем сектора | |
PUSH DS | ;сохраняем регистры |
MOV AX,SEG BUFFER | ;DS:BX должны указывать на буфер |
MOV DS,AX | ; |
MOV BX,OFFSET BUFFER | ; |
MOV DX,63 | ;логический номер сектора |
MOV CX,9 | ;читаем всю дорожку |
MOV AL,0 | ;накопитель A |
INT 25H | ;функция чтения секторов |
POP CX | ;выталкиваем со стека флаги |
POP DS | ;восстанавливаем регистры |
JNC NO_ERROR | ;если нет ошибки, то на продолжение |
CMP AH,3 | ;проверка возможных ошибок |
. | |
. | |
NO_ERROR: | ;продолжение программы |
Если при возврате флаг переноса равен 1, то произошла ошибка и в этом случае AH и AL содержат два отдельных байта статуса ошибки. Если AH = 4, то указанный сектор не найден, а если AH = 2, то диск неверно отформатирован. Если AH = 3, то была попытка записи на дискету, защищенную от записи. Все остальные значения AH говорят об аппаратной ошибке.
Hизкий уровень.
Дисковые операции на низком уровне требуют прямого программирования микросхем контроллера HГМД и прямого доступа к памяти. Поскольку эти операции взаимосвязаны, то они рассматриваются вместе в разделе {5.4.1}.
<~-5.4.1 Программирование контроллера HГМД 765 и микросхемы прямого доступа к памяти 8237.
Содержание
5.4.3 Запись в последовательные файлы.-~>