Чтение логических секторов осуществляется с помощью команды
int 25h
Перед этой командой надо сформировать следующую информацию:
DX – номер логического сектора,
AL – номер дисковода (для A номер равен 0, для B – 1, для C – 2 и т.д.),
CX – число секторов, намеченных для чтения,
DS:BX – начальный адрес области буфера.
Данная команда аналогична команде int 26h, с помощью которой производится запись из буфера на диск. Если при чтении (или записи) произошла ошибка, то флаг CF устанавливается в 1, регистры AL и AH – будут содержать коды ошибки.
Напишем программу для вывода в шестнадцатеричном виде сектора, номер которого введен с клавиатуры:
< 1 > title readsect.exe
< 2 > main segment
< 3 > assume cs:main, ds:data
< 4 > ;чтение сектора и вывод в 16-ном виде на экран
< 5 > extrn display:near, kbin:near
< 6 > extrn hex:near, hexw:near, crlf:near
< 7 > lines equ 16 ;число строк
< 8 > nchar equ 32 ;число столбцов
< 9 > ;——————————————
< 10 > go:
< 11 > mov ax,data ;инициализация
< 12 > mov ds,ax ;регистра ds
< 13 > more:
< 14 > mov dl,’?’ ;подсказка
< 15 > call display
< 16 > ;——ввод номера сектора——————
< 17 > sub bx,bx
< 18 > nexsym:
< 19 > call kbin ;ввод цифр
< 20 > cmp al,’ ‘ ;до пробела
< 21 > je back
< 22 > mov ah,0
< 23 > and al,00001111b ;взять цифру
< 24 > mov di,ax ;сохранить ax
< 25 > mov ax,bx ;число в bx
< 26 > mov si,10
< 27 > mul si
< 28 > add ax,di
< 29 > mov bx,ax ;bx=10*bx+цифра
< 30 > loop nexsym
< 31 > ;——чтение сектора———————-
< 32 > back:
< 33 > mov dx,bx
< 34 > mov al,0 ;диск A
< 35 > mov cx,1 ;один сектор
< 36 > lea bx,buffer ;чтение из A
< 37 > int 25h ;в буфер
< 38 > call crlf ;с новой строки
< 39 > ;——вывод на экран———————-
< 40 > lea bx,buffer
mov cx,lines
< 1 >
< 2 > mov si,0
< 3 > newl:
< 4 > push cx
< 5 > mov dx,si ;вывод номера байта
< 6 > push bx ;с которого
< 7 > call hexw ;начинается строка
< 8 > pop bx
< 9 > mov dl,’ ‘
< 10 > call display
< 11 > mov di,nchar
< 12 > next:
< 13 > mov dl,[bx]
< 14 > push bx
< 15 > call hex
< 16 > pop bx
< 17 > inc bx
< 18 > dec di
< 19 > jnz next ;следующий байт
< 20 > call crlf
< 21 > add si,nchar
< 22 > pop cx ;новая строка
< 23 > loop newl
< 24 > call crlf
< 25 > jmp more
< 26 > main ends
< 27 > data segment
< 28 > buffer db lines*nchar dup(?)
< 29 > data ends
< 30 > end go
Подпрограммы, вызываемые этой программой, находятся в следующем ниже модуле. (Они будут использоваться и в следующем параграфе.)
< 1 > title mylib.obj
< 2 > subr segment
< 3 > public display, kbin, hex, hexw, crlf
< 4 > public ascii
< 5 > assume cs:subr, ds:subr
< 6 > ;——подпрограммы—————-
< 7 > ;——вывод символа из dl———
< 8 > display proc
< 9 > mov ah,2
< 10 > int 21h
< 11 > ret
< 12 > display endp
< 13 > ;——ввод символа в al————
< 14 > kbin proc
< 15 > mov ah,1
< 16 > int 21h
< 17 > ret
< 18 > kbin endp
< 19 > ;——вывод байта в 16-ном виде из dl—-
< 20 > hex proc
< 21 > push bx ;сохранение
< 22 > push ds ;регистров
< 23 > mov ax,subr
< 24 > mov ds,ax
< 25 > push dx
< 26 > lea bx,table1
< 27 > mov ax,0
< 28 > mov al,dl
< 29 > clc
< 30 > shr al,1
< 31 > shr al,1
< 32 > shr al,1
< 33 > shr al,1
< 34 > xlat ;старший полубайт
< 35 > mov dl,al
< 36 > call display
pop ax
< 1 >
< 2 > and al,00001111b
< 3 > xlat ;младший полубайт
< 4 > mov dl,al
< 5 > call display
< 6 > pop ds ;восстановление
< 7 > pop bx ;регистров
< 8 > ret
< 9 > table1 db ‘0123456789ABCDEF’
< 10 > hex endp
< 11 > ;——вывод слова из dx в 16-ном виде
< 12 > hexw proc
< 13 > push bx ;сохранение
< 14 > push di ;регистров
< 15 > mov di,dx
< 16 > mov dl,dh
< 17 > call hex ;старший байт
< 18 > mov dx,di
< 19 > call hex
< 20 > mov dl,’ ‘
< 21 > call display
< 22 > pop di ;восстановление
< 23 > pop bx ;регистров
< 24 > ret
< 25 > hexw endp
< 26 >
< 27 > crlf proc
< 28 > mov dl,10
< 29 > call display
< 30 > mov dl,13
< 31 > call display
< 32 > ret
< 33 > crlf endp
< 34 >
< 35 > ascii proc ;вывод из dl в коде ASCII
< 36 > cmp dl,’a’ ;dl<‘a’?
< 37 > jb l1 ;да
< 38 > cmp dl,’z’
< 39 > ja l1
< 40 > call display
< 41 > ret
< 42 > l1:
< 43 > cmp dl,’0′
< 44 > jb l2
< 45 > cmp dl,’9′
< 46 > ja l2
< 47 > call display
< 48 > ret
< 49 > l2:
< 50 > cmp dl,’A’
< 51 > jb l3
< 52 > cmp dl,’Z’
< 53 > ja l3
< 54 > call display
< 55 > ret
< 56 > l3:
< 57 > mov dl,’.’
< 58 > call display
< 59 > ret
< 60 > ascii endp
< 61 > subr ends
< 62 > end
После выполнения компиляции и сборки:
tasm readsect
tasm mylib
tlink readsect+mylib, readsect
и запуска
readsect
появится подсказка в виде знака ‘?’. Если ввести 0, то будет выведено содержимое загрузочного сектора дискеты A:
? 0
0000 FA33C08EDOBC007C8BF4501FFB1E56FF0E1304A…
и т.д.
Упражнение. С помощью данной программы найти число секторов на дорожке и число записей в корневом каталоге. Посмотреть таблицу FAT.