На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 10 / Сектор начальной загрузки Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Сектор начальной загрузки

Самый первый сектор на диске, отформатированном под управлением операционной системы MS-DOS, всегда определяется, как "запись начальной загрузки". Эта запись содержит короткую программу, которая автоматически загружается в память, когда диск используется для загрузки операционной системы MS-DOS после подачи питания в систему или после сброса системы. Далее эта программа говорит компьютеру где ему искать на диске файлы, содержащие программы операционной системы MS-DOS. После нахождения этих файлов программа начальной загрузки загружает эти файлы в память и передает управление операционной системе MS-DOS. Поскольку количество файлов операционной системы MS-DOS и способ, которым они сохраняются, могут быть различными в зависимости от типа реализации (например, для персональных компьютеров типа "IBM PC", "COMPAQ" или "CompuPro"), содержимое записи начальной загрузки тоже может варьироваться.


В целях сохранения логичности сектор начальной загрузки всегда задается первым на отформатированном диске, независимо от того, собираетесь ли вы сделать этот диск "диском начальной загрузки" или "диском, содержащим одни только данные".


Первые три байта записи начальной загрузки всегда содержат команду перехода. При начальной загрузке команда перехода приказывает системе обойти первую часть этой записи и перейти к программе начальной загрузки. По описанию операционной системы MS-DOS версии 2.00 27 байтов записи начальной загрузки, расположенные между начальной командой перехода и программой начальной загрузки, содержат информацию о формате диска. Обращаясь к этой группе данных, программы могут получить почти всю информацию по форматированию, необходимую для диска. В таблице 11-1 представлено содержимое блока информации о форматировании находящегося в записи начальной загрузки.


Информация о форматировании в записи начальной загрузки может оказаться очень нужной при определении формата диска. Запись начальной загрузки исходно создается, когда диск форматируется командой FORMAT (для гибких дисков) или командой FDISK (для жестких дисков). Часть информации о форматировании в записи начальной загрузки под названием "OEM and Version" ("Фирма-изготовитель комплектующего оборудования и версия") обычно содержит номера версии и реализации использовавшейся операционной системы MS-DOS для создания записи начальной загрузки. Если, например, версия 3.3 операционной системы IBM-DOS использовалась для форматирования диска это поле будет содержать информацию "IBM 3.3". Остальные элементы информации по форматированию из записи начальной загрузки представляют собой набор (надмножество) из блока параметров BIOS (блок ВРВ) (см. главу 6), поскольку он уже существовал, во время форматирования диска.


Последние три элемента информации о форматировании (количество секторов на треке, количество головок и количество скрытых) секторов определяются расчетным путем и эти данные вставляются в запись начальной загрузки в процессе форматирования диска.


Программа READFMT, представленная листингом 11-1, содержит описание способа, при помощи которого информация о форматировании из записи начальной загрузки считывается с диска и отображается на экране дисплея. Кроме элементов форматирования, которые присутствуют в записи начальной загрузки, программа READFMT также осуществляет расчет нескольких других элементов, относящихся к форматированию, таких как общая системная память, общая память данных и общая емкость дисков. Программа READFMT отображает полученные результаты на экране дисплея.


   Таблица 11-1
 Информация по форматированию, содержащаяся в
  записи начальной загрузки
њњњњњњњњљњњњњњњњњњњњљњњњњњњњњљњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњ
Смещение‹ Смещение  ‹        ‹
(деся-  ‹(шестнадца-‹ Размер ‹    Содержание  поля
тичное) ‹ тиричное) ‹        ‹
њњњњњњњњќњњњњњњњњњњњќњњњњњњњњќњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњ
  0     ‹   00      ‹3 байта ‹Ближний переход к программе
        ‹  ‹        ‹начальной загрузки
њњњњњњњњќњњњњњњњњњњњќњњњњњњњњќњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњ—
  3     ‹   03      ‹8 байтов‹Название фирмы-изготовителя    ‹
        ‹  ‹        ‹оборудования и его версия   И  ‹
њњњњњњњњќњњњњњњњњњњњќњњњњњњњњќњњњњњњњњњњњњњњњњњњњњњњњњњ—  Н  ‹
 11     ‹   0B      ‹1 слово ‹Количество байтов    Б   ‹  Ф  ‹
        ‹  ‹        ‹в секторе   Л   ‹  О Ф‹
 13     ‹   0D      ‹1 байт  ‹Количество секторов  О   ‹  Р О‹
        ‹  ‹        ‹в кластере  К   ‹  М Р‹
 14     ‹   0E      ‹1 слово ‹Число зарезервиро-      B‹  А М‹
        ‹  ‹        ‹ванных секторов      П  I‹  Ц А‹
 16     ‹   10      ‹1 байт  ‹Количество таблиц    А  O‹  И Т‹
        ‹  ‹        ‹FATР  S‹  Я И‹
 17     ‹   11      ‹1 слово ‹Количество элементов А   ‹    Р‹
        ‹  ‹        ‹в каталоге  М   ‹  П О‹
 19     ‹   14      ‹1 слово ‹Количество логичес-  Е   ‹  О В‹
        ‹  ‹        ‹ких секторовТ   ‹    А‹
 21     ‹   15      ‹1 байт  ‹Байт описателя среды Р   ‹    Н‹
 22     ‹   16      ‹1 слово ‹Количество секторов  О   ‹    И‹
        ‹  ‹        ‹таблицы FAT В   ‹    Ю‹
њњњњњњњњќњњњњњњњњњњњќњњњњњњњњќњњњњњњњњњњњњњњњњњњњњњњњњњ±     ‹
 24     ‹   18      ‹1 слово ‹Количество секторов в треке    ‹
 26     ‹   1A      ‹1 слово ‹Количество  головок   ‹
 28     ‹   1С      ‹1 слово ‹Количество  скрытых  секторов  ‹
њњњњњњњњќњњњњњњњњњњњ™њњњњњњњњќњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњЊ
 30     ‹   1E     416 байтов‹Программа начальной загрузки   ‹
446     ‹   1BE     16 байтов‹Информация о разделении        ‹
        ‹  ‹        ‹памяти       ‹
462     ‹   1CE     50 байтов‹Остальная часть программы      ‹
        ‹  ‹        ‹ начальной загрузки   ‹
њњњњњњњњ™њњњњњњњњњњњ™њњњњњњњњ™њњњњњњњњњњњњњњњњњњњњњњњњњњњњњњњ±

* Для операционной системы МS-DOS версий 2.Х = 3-байтовый переход


Для операционной системы МS-DOS версий 2.Х = 2-байтовый короткий переход плюс операция NOP.


** Общее количество элементов в корневом каталоге.


*** Байты описателя среды не всегда являются действительными, как для операционной системы MS-DOS версии 2.0


**** Относится только к жестким дискам, содержащим таблицы начальной загрузки; эта область не используется на гибких дисках.


        Листинг 11-1. Программа READFMT
----------------------------------------------------------------
   PAGE 50,132
   TITLEREADFMT.ASM/.EXE
  .SALL ; подавить выдачу макрорасширений в программе
  .8086 ; пользоваться  только командами
        ; микропроцессоров 8086/8088
;*************************************************************
;**  Программа READFMT  Версии 1.00
;**     Настоящая  программа считывает сектор начальной заг-
;** рузки с любого диска, расшифровывает обнаруженный в  за-
;** писи  начальной загрузки блок параметров BIOS(BPB),и вы-
;** водит на экран дисплея эту информацию и некоторую другую
;** расчетную информацию.
;**
;**     Примечание: во время создания этой программы  перек-
;** лючатель  LINK  "/СР:1"  должен использоваться для того,
;** чтобы во время загрузки программы, ей распределялось  бы
;** действительно  нужное  количество  памяти.  По умолчанию
;** максимальным объемом распределяемой памяти в том случае,
;** когда "/СР:1" не задан, является вся память  выше  точки
;** загрузки  программы, что вызывает завершение программы с
;** выдачей сообщения об ошибке, потому что она не в состоя-
;** нии сделать дополнительное  перераспределение памяти  во
;** время своей работы.
;*************************************************************
;
;   СОСТАВ:
INCLUDE       stdequ.inc  ; включить стандартный файл равенств
INCLUDE       stdmac.inc  ; включить стандартный файл макросов
INCLUDELIB    stdlib.lib  ; включить  стандартную библиотеку
        ; STDLIB.LIB во временное редакти-
        ; рование
        ;
; Заявки на программы обращения к внешним  библиотекам,
; находящиеся в STDLIB.LIB
EXTRN  dosv2con:NEAR      ; получить и вывести на экран текущую
        ; версию DOS
EXTRN  dosver:NEAR        ; дать текущую версию  DOS
EXTRN  bin2dec2:NEAR      ; вывести на экран дисплея DX:AX в
        ; десятичных цифрах кода ASCII
        ; (если  регистр  DX=),  регистр AX
        ; считается беззнаковым
;
; - - - - - -  ИНИЦИАЛИЗАЦИЯ - - - - - - - - - - - - - - - - - -
;
.MODEL   SMALL   ; малая модель
.STACK  2048     ; создать 2-Кбайтовый  стек
;
;*************************************************************
;  ГЛАBHАЯ  ПРОГРАММА
;
.DATA
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;      Cсылки и обращения к компонентам записи начальной заг-
; рузки,  считанной  с диска и помещенный в блок памяти, осу-
; ществляются при помощи ES.  Обращения  производятся  только
. компонентам  блока  "Блок параметров BIOS"(BPB); первые три
; байта и все данные расположенные после  области  блока  ВРВ
; записи начальной загрузки, игнорируются.
;
bootrecord     STRUC
BootJump       db     3 DUP (?) ; исходная команда перехода
OEMstring      db     8 DUP (?) ; фирма-изготовитель и версия
     ; операционной системы MS-DOS
SectorBytes    dw     ?; количество байтов в секторе
ClusterSec     db     ?; количество секторов в кластере
ReservedSec    dw     ?; зарезервированные сектора
FATcopies      db     ?; количество копий таблицы FAT
DirEntries     dw     ?; количество элементов в
     ; корневом каталоге
TotalSectors   dw     ?; общее количество  секторов
     ; диска (100% диска)
MediaDescrip   db     ?; описатель среды
FATsectors     dw     ?; количество секторов, занятых
     ; одной таблицей FAT
TrackSectors   dw     ?; количество секторов в треке
Heads dw     ?; количество головок
HiddenSectors  dw     ?; количество скрытых секторов
bootrecord     ENDS
;
.CODE
;
; Cохранение локальных данных (храните эти определения
; в сегменте  программы)
;
DSsavedw    seg DGROUP ; память для регистра DS
;
.DATA
PSPsegdw     ?; сегмент PSP (Префикс про-
     ; граммного сегмента)
.CODE
main     PROC NEAR     ; начало основного процесса
;
;***********************************************************
; ЗАПУСК ПРОГРАММЫ
;***********************************************************
     mov   ds,DSsave  ; инициализация DS
     mov   ax,es      ; получить адрес сегмента PSP
     mov   word ptr PSPseg,ax  ; ....... и сохранить его
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Bывести на экран дисплея сообщение о запуске
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

      @DisStr Start1_Msg       ; вывести на экран дисплея
    ; сообщение о запуске
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Получить номер/имя дисковода
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov   di,80h; командная строка
cmp   byte ptr es:[di],0      ; есть ли параметры?
je    get_default_drive       ; нет, получить дисковод
   ; по умолчанию
cmp   byte ptr es:[di+3],':'  ; присутствует ли двое-
   ; точие?
jne   get_default_drive       ; нет, получить дисковод
   ; по умолчанию
get_disk_drive:      ; получить дисковод в
   ; командной строке
xor   ah,ah ; очистить AH
mov   al,byte ptr es:[di+2]   ; получить заданный
   ; дисковод
cmp   al,">"; использовалась ли
   ; переадресовка?
je    get_default_drive       ; да, получить дисковод
   ; по умолчанию
cmp   al,61h; дисковод задан буквами
   ; верхнего регистра?
jge   convert_upper  ; да, выполнить преобра-
   ; зование из символов
   ; ASCII верхнего регистра
sub   al,40h; иначе  выполнить  из
   ; символов ASCII  нижнего
   ; регистра
jmp   short test_drive        ; и продолжить
convert_upper:
sub   al,60h; преобразование символов
   ; ASCII верхнего регистра
test_drive:
cmp   al,1  ; число меньше единицы?
jl    bad_drive      ; да, выйти на сообщение
   ; об ошибке
dec   al    ; иначе выполнить А:=0,
   ; ...... В: = 1  и т.д.
cmp   al,25 ; результат предыдущeй
   ; команды > 25 (>Z:)?
jg    bad_drive      ; да, выйти на сообщение
   ; об ошибке
jmp   short drive_used        ; иначе  сохранить
   ; указанный дисковод
get_default_drive:
mov   ah,19h; получить дисковод
   ; по умолчанию
@DosCall
drive_used:
mov   byte ptr DiskDrive,al   ; сохранить дисковод
jmp   short drive_end; и продолжить
bad_drive:
@DisStr BadDrive_Msg ; иначе вывести на экран
   ; сообщение об ошибке
   ;(синтаксической ошибке)
jmp   terminate      ; и выйти в DOS
drive_end:
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Cчитывание в память информации сектора начальной загрузки.
; После возвращения ES:DI(ES:0) указывает на  блок  памяти,
; содержащий  запись  начальной загрузки.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.DATA
BootSeg   dw    ?    ; сохранение адреса
   ; сегмента блока памя-
   ; ти содержащего копию
   ; записи начальной
   ; загрузки
.CODE
 mov   bx,40h        ; распределить 1024 байта
 call  memalloc      ; распределить  блок
 jnc   read_boot     ; продолжить, если не
   ; было ошибок
 call  mem_err_handler        ; иначе обработать ошибку
 jmp   terminate     ; и выйти в DOS
   ;
;  ;
read_boot:
 mov   word ptr BootSeg,ax    ; сохранить адрес сег-
   ; мента
 push  ax   ; и  сохранить  его
 mov   al,byte ptr DiskDrive  ; получить  дисковод
   ; для считывания
 xor   ah,ah; очистить AH
 pop   ds   ; получить адрес сег-
   ; мента нового блока
 mov   dx,0 ; считать логический
   ; сектор 0
 mov   cx,1 ; считать в один сектор
 mov   bx,0 ; поместить данные в DS:0
 jnt   25h  ; считать диск
 jc    read_boot_error        ; выйти, если произошла
   ; ошибка
 popf       ; очистить флаги, про-
   ; толкнутые в стек во
   ; время прерывания
   ; "int 25h"
 mov   ds,DSsave     ; повторная инициали-
   ; зация области DS
 mov   ax,word ptr BootSeg    ; получить адрес сегмен-
   ; та начальной загрузки
 mov   es,ax; и инициализировать в
   ; него ES
 xor   di,di; со смещением 0
 jmp   end_read_boot  ; и продолжить
;
read_boot_error:
 popf       ; очистить флаги, про-
   ; толкнутые в стек во
   ; время прерывания
   ; "int 25h"
 mov   ds,DSsave     ; повторная инициали-
   ; зация области DS
 @DisStr ReadError_Msg       ; выйти с выдачей
 jmp   terminate     ; сообщения об ошибке
;
end_read_boot:
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;     Проверить,  чтобы  считанная  запись начальной загрузки
; содержала  нужную  нам  информацию.  Если  диском  является
; 160-Кбайтный или 320-Кбайтный гибкий диск, запись начальной
; загрузки  будет  содержать  нужную нам информацию блока ВРВ
; (это может оказаться правильным также для некоторых нестан-
; дартных форматов дисков , в случае чего таблица FAT  должна
; считываться  с  целью  получения  байта идентификатора (ID)
; формата. Этот байт требуется для определения формата  диска
; (является  ли  диск  160-Кбайтным  для -версии операционной
; системы DOS 1.0 или; 360-Кбайтным для  версии  операционной
; системы DOS 1.1.
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;

 mov    bx,20h     ; распределить 512 бай-
 ; ... тов (32 параграфа)
 call   memalloc   ; распределить блок памяти
 jnc    read_fat   ; продолжить,  если ошибок
 ; не было
 call   mem_er_handler      ; иначе перейти на про-
 ; грамму обработки ошибок
 jmp    terminate  ; и выйти в DOS
;
read_fat:
.DATA
FATSeg    dw     ?   ; адрес  сегмента  из
   ; таблицы  FAT
.CODE
 mov    word ptr FATseg,ax    ; сохранить адрес сег-
   ; мента FAT
 push   ax  ; и сохранить его
 mov    al,byte ptr DiskDrive ; получить дисковод для
   ; считывания
 xor    ah,ah        ; очистить  AH
 pop    ds  ; получить адрес сег-
   ; мента нового блока
 mov    dx,1; очистить логический
   ; сектор 1
 mov    cx,1; считать в один сектор
 mov    bx,0; сохранить данные в DS:0
 jnt    25h ; читать диск
 jnc    process_FAT  ; продолжить, если ошибок
   ; не было
 popf       ; иначе, сбросить флаги
 mov    ds,DSsave    ; повторная инициализа-
   ; ция области DS
 @DisStr ReadError_Msg        ; выйти с сообщением об
   ; ошибке
 mov    ax,word ptr FATSeg    ; получить адрес сегмента
   ; начальной  загрузки
 call   memfree      ; освободить блок
 jnc    end_fat_err  ; выйти, если не было
   ; ошибок
 call   mem_err_handler       ; иначе, вывести на
   ; экран дисплея сообще-
   ; ние об  ошибке
end_fat_err:
 jmp    terminate    ; выйти в DOS
;
process_FAT:
 popf       ; очистить флаги, про-
   ; толкнутые в стек во
   ; время прерывания
   ; "int 25h"
 mov    ds,DSsave    ; повторная инициализа-
   ; ция области DS
 mov    ax,word ptr FATSeg    ; получить адрес сегмента
   ; начальной  загрузки
 mov    es,ax        ; и инициализировать ES
 xor    di,di        ; в него со смещением 0
.DATA
FAT_ID    db     ?   ; байт идентификации
   ; (ID) из таблицы FAT
.CODE

 mov    al,byte ptr es:[di]   ; получить элемент О
   ; таблицы FAT
 mov    byte ptr FAT_ID,at    ; и сохранить его как байт
 call   memfree      ; освободить сегмент
   ; таблицы FAT
   ; (адрес находится в ES)
 jnc    comp_byte_id ; продолжить, если не
   ; было ошибок
 call   mem_err_handler       ; иначе вывести на экран
   ; сообщение  об ошибке
 jmp    terminate    ; выход в операционную
;  ; систему DOS
comp_byte_id:
 mov    ax,word ptr BootSeg   ; указать на сегмент
   ; начальной загрузки
 mov    es,ax        ; ES:0 указать на
 xor    di,di        ; запись  начальной
   ; загрузки
 mov    al,byte ptr FAT_ID    ; получить идентифика-
   ; тор (ID) таблицы FAT
 cmp    al,byte ptr es:[di].MediaDescrip ; и сравнить
   ; с битом ID
   ; в записи  начальной
   ; загрузки
 jne    chk_dos1_fmt ; если иначе, то решить
 jmp    end_read_fat ; иначе, продолжить
chk_dos1_fmt:
 cmp    al,0FEh      ; это  160-Кбайтный
   ; гибкий диск?
 je     init_dos1_fmt; да, инициализировать
   ; запись начальной
   ; загрузки
 cmp    al,0FFh      ; иначе, это 320-Кбайт-
   ; ный  гибкий  диск?
 je     init_dos1_fmt; да, инициализировать
   ; запись начальной
   ; загрузки
.DATA
UnknownMedia db "Невозможно определить формат диска."
    db  "Возможно, это диск не "
    db  "операционной системы MS-DOS.",CR,LF,"$"
.CODE
 @DisStr UnknownMedia        ; вывести на экран
  ; сообщение об ошибке
 jmp     terminate  ; выход в операционную
  ; систему DOS
init_dos1_fmt:
       ; Инициализировать элементы  формата, которые одинаковы
       ; для 160-Кбайтных и 320-Кбайтных форматов дисков:
 mov     word ptr es:[di+3],"D"   ; передать по буквам
       ; "DOS  1.X"
 mov     word ptr es:[di+4],"O"   ; в поле ОЕМ и
 mov     word ptr es:[di+5],"S"   ; версии DOS записи
 mov     word ptr es:[di+6]," "   ; начальной загрузки
 mov     word ptr es:[di+7],"1"
 mov     word ptr es:[di+8],"."
 mov     word ptr es:[[b]di].SectorBytes,512 ; коли-
 ; чество байтов в секторе
 mov     word ptr es:[di].ReservedSec,1   ; зарезер-
     ; вированные секторы
 mov     word ptr es:[di[.FATcopies,2     ; количест-
     ; во копий таблицы FAT
 mov     word ptr es:[di].FATsectors,1    ; количество
     ; секторов таблицы  FAT
 mov     word ptr es:[di].TrackSectors,8  ; количество
     ; секторов в треке
 mov     word ptr es:[di].HiddenSectors,0 ; количество
     ; скрытых секторов
 cmp     al,0FEh      ; это гибкий 160-Кбайтный диск?
 je      init_160K    ; да, инициализировать запись
    ; начальной загрузки
 cmp     al,0FFh      ; иначе, это гибкий 320-Кбайтный
    ; диск?
 je      init_320K    ; да, инициализировать запись
    ; начальной загрузки
;
init_160K:
 mov word ptr es:[di.9],"0" ; это версия
 ; "DOS 1.0"?
 mov     word ptr es:[di.10],"?" ;
 mov     byte ptr es:[di].ClusterSec,1    ; количество
      ; секторов в
      ; кластере
 mov     word ptr es:[di].DirEntries,64   ; количество
      ; элементов
      ; в каталоге
 mov     word ptr es:[di].TotalSektors,320 ; общее ко-
       ; личество
       ; секторов
       ; на диске
 mov     byte ptr es:[di].MediaDescrip,0FEh ; описатель
        ; носителя
 mov     word ptr es:[di].Heads,1  ; количество головок
 jmp end_read_fat
;
init_320K:
 mov     word ptr es:[di.9],"1"      ; это версия
 ; "DOS 1.1"?
 mov     word ptr es:[di.10],"?"
 mov     byte ptr es:[di].ClusterSec,2    ; количество
      ; секторов в
      ; кластере
 mov     word ptr es:[di].DirEntries,112  ; количество
      ; элементов
      ; в каталоге
 mov     word ptr es:[di].TotalSektors,640 ; общее ко-
       ; личество
       ; секторов
       ; на диске
 mov     byte ptr es:[di].MediaDescrip,0FFh ; описатель
        ; носителя
 mov     word ptr es:[di].Heads,2  ; количество головок
 jmp end_read_fat
;
end_read_FAT:
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;      Вычислить величины, отсутствующие в  блоке  параметров
; BIOS.  Примечание:  ES:DI  (смещение 0) должен указывать на
; начало записи начальной загрузки, считанной в  память.  Все
; расчетные значения сохраняются в сегменте данных.
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
get_new_values:
  xor    di,di    ; очистить DI
;
; Рассчитать общее количество секторов, используемых для всех
; копий таблицы  FAT.
       xor    ah,ah        ; очистить AH
       mov    al,byte ptr es:[di].FATcopies  ; получить копии
; таблицы FAT
       xor    dx,dx        ; очистить DX
       mov  bx,word ptr es:[di].FATsectors   ; получить число
; секторов таблицы
; FAT
       mul    bx  ; умножить на
; это число
       mov    word ptr TotalFATSec,ax      ; сохранить ре-
       ; зультат в 1 слове
;
; Рассчитать общее  количество  секторов,  используемых всеми
; элементами  каталога
       mov    ax,word ptr es:[di].DirEntries ; получить общее
; количество эле-
; ментов корневого
; каталога

  mov    bx,word ptr DirEntBytes    ; получить размер
; в байтах эле-
; ментов каталога
  xor    dx,dx    ; очистить  DX
  mul    bx       ; умножить
  mov    bx,word ptr       ;
es:[di].SectorBytes     ; получить количество байтов в секторе
  xor    dx,dx    ; очистить  DX
  div    bx       ; разделить
  mov    word ptr DirSectors,ax     ; сохранить ре-
; зультат в 1 слове
;
; Вычислить  общее  количество цилиндров
      mov    ax,word ptr es:[di].TotalSectors  ; получить общее
      ; количество секторов
      mov    bx,word ptr es:[di].TrackSectors   ; получить ко-
        ; личество секторов в  треке
      xor    dx,dx        ; очистить  DX
      div    bx; и разделить на него
      mov    bx,word ptr es:[di].Heads ; получить число головок
      xor    dx,dx      ; очистить  DX
      div    bx; и разделить на него
      cmp    word ptr es:[di].HiddenSectors ; скрытые сектора?
      je     store_cyl    ; нет, теперь мы
 ; имеем общее количество цилиндров
      mov    cx,word ptr es:[di].HiddenSectors ; иначе, скрытые
   ; сектора = 1
      cmp    cx,word ptr es:[di].TrackSectors    ; цилиндр?
      je     add_cyl     ; да
      mov    ax,0        ; иначе, произошла ошибка
      jmp    short store_cyl      ;
add_cyk:
   add   ax,1     ; добавить дополнительный цилиндр
store_cyl:
   mov   word ptr Cylinders,ax ; сохранить результат
;
; Получить  общее количество байтов на всем (100%) диске
   mov   ax,word ptr es:[di].TotalSectors ; получить
       ; общее количество секторов
   xor   dx,dx        ; очистить DX
   mov   bx,word ptr es:[di].SectorBytes  ; получить
     ; количество байтов в секторе
   mul   bx    ; и умножить на него
   mov   word ptr TotalBytes,ax  ; и сохранить резуль-
      ; тат, состоящий из двух слов
   mov   word ptr TotalBytes.2,dx ; из AX и DX
;
; Получить общее количество секторов данных (в которых могут
; сохраняться файлы)
   mov   ax,word ptr es:[di].TotalSectors ; получить
       ; общее количество секторов
xor   dx,dx; очистить  DX
  sub   ax,word ptr es:[di].ReservedSec ; вычесть
       ; зарезервированные секторы
  sub   ax,word ptr TotalFATSec  ; вычесть общее
 ; количество секторов таблицы FAT
; (все копии таблицы FAT)
       sub   ax,word ptr DirSectors    ; вычесть  секторы
   ; корневого каталога
       mov   word    ptr DataSectors,ax ; и сохранить результат
;
; Получить количество байтов в кластере
        xor   ah,ah; очистить AH
        mov   al,byte ptr es:[di].ClusterSec  ; получить секторы
 ; кластера
        xor   dx,dx; очистить DX
        mov   bx,word ptr es:[di].SectorBytes ; получить байты
 ; сектора
        mul   bx    ; и умножить на это число
        mov   word ptr ClusterBytes,ax  ; и сохранить результат
;
; Получить общее количество секторов
        mov   ax,word ptr DataSectors ; получить секторы данных
        xor   bh,bh    ; очистить BH
        mov   bl,byte ptr es:[di].ClusterSec ; получить секторы
; кластера
        xor   dx,dx   ; очистить DX
        div   bx    ; разделить на количество секторов
        mov   word ptr TotalClusters,aх ; и сохранить результат
    ; в слове
;
; Получить количество битов в элементе таблицы FAT.
; Всегда 12 битов, если общее количество кластеров = 4,085 или
; меньше.
; Всегда 16 битов, если общее количество кластеров больше
; 4,085.
        cmp   word ptr TotalClusters,4085       ; общее коли-
   ; чество кластеров больше 4085?
        jle   got_entry_size  ; нет используйте 12-битовое
   ; значение по умолчанию
        mov   al,16  ; иначе - 16-битовое значение
        mov   byte ptr FATentryBits,al ; и сохранить значение
got_entry_size:
;
; Получить общее количество байтов данных (используемых байтов)
        mov   ax,word ptr DataSectors   ; получить общее коли-
    ; чество секторов
        xor   dx,dx,  ; очистить DX
        mov   bx,word ptr es:[di].SectorBytes ; получить байты
    ; сектора
        mul   bx   ; и умножить на это число
        mov   word ptr DataBytes,ax  ; и  сохранить результат
 ; в 2 словах
        mov   word ptr DataBytes,2,dx   ; из AX и DX
;
; Вычислить регистр  диска  в  килобайтах или мегабайтах
        mov   ax,word ptr TotalBytes    ; получить общее коли-
  ; чество байтов на диске
        mov   dx,word ptr TotalBytes.2  ; ... (двойное слово)
        mov   cx,1024 ; установить делитель
        div   cx  ; и получить значение в килобайтах
        mov   word ptr KBytes,ax        ; сохранить значение
        cmp   ax,1000     ; вычислить в Мегабайтах?
        jl    dis_info    ; нет,  мы  закончили
        mov   bx,1000     ; иначе установить делитель
        xor   dx,dx       ; очистить регистр DX
        div   bx ; и получить мегабайты
        mov   word ptr Mbytes,ax   ; сохранить главное значение
        mov   word ptr Mbytes2,dx  ; и сохранить часть, если
        ; таковая имеется
        cmp   dx,0        ; есть ли часть?
        je    megabytes_end        ; нет,  мы  закончили
        mov   ax,dx       ; иначе установить делимое
        mov   bx,10       ; установить  делитель
        xor   dx,dx       ; очистить регистр DX
;
; Цикл удаления хвостовых нулей
compress_loop:
   div   bx      ; разделить регистр AX на 10
   cmp   dx,0       ; есть ли остаток?
   jne   megabytes_end       ; да, мы закончили
   mov   word ptr Mbytes2,ax ; иначе сохранить новое
  ; сжатое значение
   jmp   short compress_loop ; и снова  повторить
megabytes_end:
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Отобразить на экране дисплея информацию о диске
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
dis_info:
 @DisStr Start2_Msg ; отобразить на экране дисплея
    ; первую часть сообщения о  дисководе
 xor   ah,ah        ; очистить регистр AH
 mov   al,byte ptr DiskDrive ; и вывести на экран
  ; имя дисковода
 inc   al; дать ему используемый номер
 add   al,40h     ; преобразовать его  в  буквы
;        ; ... ASCII верхнего регистра
 @DisChr al       ; и вывести его на экран
 @DisChr ':'      ; после него поставить двоеточие
 @Newline
;
 @DisStr OEM_Msg ; вывести на экран сообщение OЕМ
        ; (о фирме-производителя и версии)
 push  di   ; сохранить DI
 mov   di,bootrecord.OEMstring ; указать строку ОЕМ
 mov   cx,8 ; установить счетчик  символов
more_char:     ; ввести дисплейный цикл
 mov   al,byte ptr es:[di]    ; получить символ
 @DisChr al   ; отобразить символ на экране дисплея
 inc   di   ; указать на следующий символ
 dec   cx   ; счетчик десятичных символов
 cmp   cx,0 ; все сделаны ?
 jg    more_char     ; нет, вывести следующий символ
 @NewLine   ; иначе, мы закончили
 pop   di   ; восстановить DI
;
 @DisStr  MeliaDescrip_Msg  ; отобразить на экране
 ; описатель  носителя
 xor   ah,ah,      ; очистить регистр AH
 mov   al,byte ptr es:[di].MediaDecrip ; считать
 ; байтовое значение
 @DisNum ax,16,2   ; отобразить две шест-
 ; надцатиричные цифры
 cmp   byte ptr es:[di].MediaDescrip,0F8h ;жесткий диск?
 je fixed_disk   ; да, отобразить на экране сообщение
 @DisStr RemovableMedia_Msg ; иначе - сменный диск
 jmp   short media_size     ; и теперь сделать размер
 ; в Kb/Mb
fixed_disk:
    @DisStr FixedMedia_Msg     ; отобразить на экране
     ; сообщение о жестком носителе
media_size:
    cmp   word ptr Mbytes,0  ; показывать в Мегабайтах
    je    show_kilobytes     ; нет, в Килобайтах
    mov   ax,word ptr Mbytes ; да, задать в Мегабайтах
    @DisNum ax,10,1,0        ; вывод десятичного числа
  ; без знака
    cmp   word ptr Mbytes2,0


; есть ли часть?
    je    done_mbytes        ; нет, мы закончили
    @DisChr '.'     ; иначе, вывести на
  ; экран десятичную точку
    mov   ax,word ptr Mbytes2 ; задать часть в Мбайтах
    @DisNum  ax,10,1,0       ; вывод десятичного числа
  ; без знака
done_mbytes:
    @DisChr 'M'       ; вывести на экран сим-
    ; вол "М"  (Мегабайт)
    jmp   short done_media     ; и мы закончили
show_Kilobytes:
    mov  ax,word  ptr Kbytes   ; получить значение в
    ; Килобайтах
    @DisNum ax,10,1,0 ; вывод десятичного
    ; числа без знака
    @DisChr 'K' ; вывести на экран символ "К" (Кбайт)

done_media:
    @DisStr Media_Msg        ; вывести на экран конец
  ; сообщения
    @NewLine
;
    @DisStr Cylinders_Msg     ; отобразить на экране
; дисплея общее количество цилиндров (треков)
    cmp   word ptr Cylinders,0   ; была ли ошибка?
    jne   show_cyl        ; нет, отобразить на экране
        ; дисплея общее количество цилиндров
    @DisChr '?'  ; иначе, вывести на экран символ
        ; "знак вопроса"
    jmp   short end_cyl; и закончить
show_cyl:
    mov   ax,word ptr Cylinders ; получить значение
    @DisNum ax,10,1,0  ; и отобразить его на
     ; экране дисплея
end_cyl:
       @NewLine
;
       @DisStr Heads_Msg; отобразить на экране
      ; количество головок
       mov   ax,word ptr es:[id].Heads ; получить значение слова
       @DisNum ax,10,1,0    ; вывод десятичного числа без знака
       @NewLine
;
       @DisStr TrackSectors_Msg   ; отобразить на экране
 ; дисплея количество секторов в треке
       mov   ax,word ptr es:[di].TrackSector  ; получить
    ; значение слова
       @DisNum ax,10,1,0  ; вывод десятичного числа без знака
       @NewLine
;
       @DisStr SectorBytes_Msg ; отобразить на экране
      ; дисплея  количество байтов в секторе
       mov   ax,word ptr es:[id].SectorBytes ; получить значе-
; ние слова
       @DisNum ax,10,1,0   ; вывод десятичного числа без знака
       @NewLine
;
       @DisStr НiddenSectors_Msg ; отобразить на экране
; дисплея количество скрытых секторов
       mov ax,word ptr es:[di].HiddenSectors ; получить зна-
  ; чение слова
       @DisNum ax,10,1,0   ; вывод десятичного числа без знака
       cmp  word ptr es:[di].HiddenSectors,0 ; есть ли
       ; скрытые  сектора?
       je    hidden_done ; нет, мы закончили
       @DisStr PartitionInfo_Msg  ; иначе, дать инфор-
       ; мацию о разделении
hidden_done:
      @NewLine
;
      @DisStr TotalSectors_Msg     ; отобразить на экране
    ; дисплея общее  количество  секторов  диска
      mov   ax,word ptr es:[di].TotalSectors   ; получить
     ; значение слова
      @DisNum ax,10,1,0 ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr TotalBytes_Msg     ; отобразить на экране
    ; дисплея общее количество байтов на диске
      mov   ax,word ptr TotalBytes ; получить  значение,
       ; состоящее из двух слов и ...
      mov   dx,word ptr TotalBytes.2 ; поместить его в
        ; регистры  AX и DX
      call  bin2dec2      ; и вывести на экран
        ; результат DX:AX
      @NewLine
;
      @DisStr ReservedSec_Msg    ; отобразить на экране
; дисплея количество зарезервированных секторов
      mov   ax,word ptr es:[di].ReservedSec    ; получить
      ; значение слова
      @DisNum ax,10,1,0  ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr FATsectors_Msg    ;отобразить на
    ; экране дисплея количество секторов
    ; в одной таблице FAT
      mov   ax,word ptr es:[di].FATsectors ; получить
      ; значение слова
      @DisNum ax,10,1,0 ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr FATcopies_Msg    ; отобразить на  экране дисплея
    ; количество копий таблицы FAT
      xor   ah,ah ; очистить AH
      mov   al,byte ptr es:[di].FATcopies  ; получить
   ; значение байта
      @DisNum  ax,10,1,0 ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr TotalFATsectors_Msg  ; отобразить на экране
; дисплея общее количество секторов для
; всех таблиц FAT
      mov   ax,word ptr TotalFATSec  ; получить значение слова
      @DisNum ax,10,1,0    ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr DirEntries_Msg; отобразить на экране
 ; дисплея количество элементов корневого каталога
      mov   ax,word ptr es:[di].DirEntries ; получить значение
       ; слова
      @DisNum ax,10,1,0    ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr DirSektors_Msg       ; отобразить  на экране
    ; дисплея  общее количество секторов
    ; корневого каталога
      mov   ax,word ptr DirSectors ; получить значение слова
      @DisNum ax,10,1,0   ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr DataSectors_Msg      ; отобразить на экране
;   ; дисплея общее  количество  секторов данных
      mov   ax,word ptrDataSectors ; получить значение слова
      @DisNum ax,10,1,0   ; вывод десятичного числа без знака
      @NewLine
;

      @DisStr ClusterSectors_Msg        ; отобразить на экране
  ; дисплея количество секторов  в  кластере
      xor   ah,ah     ; очистить AH
      mov   al,byte ptr es[di].ClusterSec ; получить значение
    ; байта
      @DisNum  ax,10,1,0   ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr ClusterBytes_Msg ; отобразить на экране
     ; дисплея количество байтов в  кластере
      mov   ax,word ptr ClusterBytes ; получить значение слова
      @DisNum ax,10,1,0   ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr Totalclusters-Msg     ; отобразить на экране
        ; дисплея общее количество кластеров
      mov   ax,word ptr Totalclusters ; получить значение слова
      @DisNum ax,10,1,0   ; вывод десятичного числа без знака
      @NewLine
;
      @DisStr FATentrySize_Msg; отобразить на экране
       ; дисплея размер каждого элемента таблицы  FAT
      xor   ah,ah    ; очистить AH
      mov   al,byte ptr FATentryBits   ; получить значение
   ; байта
      @DisNum ax,10,1,0   ; вывод десятичного числа без знака
      @DisStr Bits_Msg       ; указать, что значение
  ; задано в битах
      cmp   byte ptr FATentryBits,12  ; определить, сколько
  ; имеется байтов
      jg   dis_two_bytes
      @DisStr SmallFAT_Msg   ; элемент таблицы FAT = 1,5 байта
      jmp  short show_fat_done
dis_two_bytes:
    @DisStr LargeFAT_Msg     ; элемент таблицы
  ; FAT = 2 байта
show_fat_done:
;
        @NewLine
;
        @DisStr DataBytes_Msg  ; отобразить на экране дисплея
; количество байтов данных на диске
mov   ax,word ptr DataBytes     ; получить значение
mov   dx,word ptr DataBytes.2   ; состоящее из двух
   ; слов и поместить его в регистры AX и DX
call  bin2dec2       ; и вывести его на экран дисплея
@NewLine
;
push   es   ; сохранить текущее значение ES
mov   ax,word ptr BootSeg   ; получить адрес сегмента
 ; распределенного блока
mov   es,ax   ; и назначить ему ES
call  memfree ; освободить блок
pop   es; восстановить значение ES
;
terminate:
@ExitToDOS       ; завершить  программу
;
;************************************************************
; Конец программы
;************************************************************
main   ENDP      ; конец главного процесса
;
;************************************************************
; Запуск стандартных программ
;*************************************************************
;
;+++++++++++++++++++++++++++++++++++++++++++++++++
; MEM_ERR_HANDLER: Описатель ошибки распределения памяти
; (освобождения памяти) изменения размера.
;BXОД:       AX = код ошибки
;   BX = максимальный доступный блок памяти
;        (если код  ошибки  =  8)
;   ЕX = адрес сегмента распределенного блока
;        (если код ошибки = 9)
;
;ВЫХОД:        ни  один  (все  регистры восстановлены)
;
;Вызываемые стандартные программы : нет
;- - - - - - - - - - - - - - - - - - - - - - - - -
mem_err_handler PROC  NEAR
;
    cmp   ax,7     ; очищенные от мусора управляющие
 ;  блоки  памяти ?
    jne   mem_error8     ; нет, продолжить проверку
.DATA
NranshedMemErr_Msg db  "Ошибка распределения памяти:"
    db"разрушены управляющие блоки памяти.",CR,LF,"$"
.CODE
        @DisStr TrashedMemErr_Msg    ; да, выйти с сообщением
        ret        ; возврат
;
mem_error8:
    cmp   ax,8    ; недостаточно памяти ?
    jne   mem_error9       ; нет, продолжить проверку
.DATA
InsuffMemErr_Msg  db  "Ошибка распределения памяти:"
db  "недостаточно памяти",CR,LF
db  "Hаибольший доступный блок памяти = $"

.CODE
@DisStr InsuffMemErr_Msg   ; да, выйти с сообщением
@DisNum bx,10,1,0 ; доступен
@NewLine  ; вывести на экран пустую строку
ret      ; возврат
;
mem_error9:
 cmp   ax,9      ; неправильный  адрес блока памяти?
 jne   mem_err_unknown    ; нет, неизвестная причина
.DATA
IncorrSegAddr_Msg db "Неправильный адрес сегмента для изменения"
db "изменения размера/освобождения.",CR,LF
db "Адрес сегмента = $"
.CODE
    @DisStr IncorrSegAddr_Msg   ; вывести на экран
   ; дисплея сообщение об ошибке
    @DisNum es,16,4  ; вывести на экран дисплея адрес
   ; сегмента
    @NewLine; вывести на экран пустую строку
    ret     ; возврат
;
mem_err_unknown:
.DATA
UnknownMemErr_Msg db "Hеизвестная  ошибка распределения/"
        db "/изменения размера/освобождения памяти.",CR,LF,"$"
.CODE
        @DisStr UnknownMemErr_Msg  ; вывести на экран
        ; дисплея сообщение
        ret
;
mem_err_handler ENDP
;
;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; MEMALLOC: Распределить блок памяти заданного размера в
; параграфах  (1 параграф = 16 байтам).
;
;BXОД:       BX = размер в 16-байтовых параграфах запрошенного
;        блока
;
;ВЫХОД:      "Успешно", если признак переноса = 0  при
;    AX = адрес сегмента распределенного
;    блока памяти (BX восстанавливается)
;    "Сбой",  если признак переноса = 1 при
;     AX = код ошибки
;   7 = разрушены управляющие блоки памяти
;   8 = недостаточно памяти
;     BX = наибольший  доступный блок памяти
; в параграфах
; Вызываемые стандартные программы: нет
;- - - - - - - - - - - - - - - - - - - - - - - - - -- - -
memalloc PROC      NEAR
;
    push  bp      ; сохранить указатель базы
    push  bx      ; сохранить  регистр  BX
    mov   bp,sp     ; инициализировать указатель базы
;
    xor   al,al     ; очистить AL
    mov   ah,48h    ; загрузить функцию распределения
  ; памяти
    @DosCall        ; выполнить распределение памяти
    jnc   end_memalloc     ; выйти, если нет ошибок с
 ; с адресом сегмента в регистре AX
 ; иначе, выйти с установленным
 ; признаком переноса;
    mov   word ptr [bp],bx ; блок максимального размера
; (BX) и код ошибки в AX
;
end_memalloc:
    pop  bx; восстановить регистр BX
    pop  bp; восстановить указатель базы
    ret
memalloc     ENDP   ;
;
;
;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; MEMFREE:  Освобождение  памяти : освободить блок памяти,
; распределенный ранее стандартной программой MALLOC
;
;BXОД:     ES = адрес сегмента  распределенного блока памяти
;
;ВЫХОД:   "Успешно", если признак переноса = 0
; (ES восстанавливается)
;
;"Сбой",  если признак переноса = 1 при
; AX = код ошибки
;     7 = разрушены управляющие блоки памяти
;     9 = неправильный адрес (ES  восстанавливается)
;
; Вызываемые стандартные программы: нет
;- - - - - - - - - - - - - - - - - - - - - - - - - -- - -
memfree      PROC      NEAR
;
    push   bp      ; сохранить указатель базы
    push   es
    push   ax      ; сохранить регистр AX
    mov    bp,sp   ; инициализировать указатель базы
;
    xor    al,al    ; очистить AL
    mov    ah,49h   ; загрузить функцию
  ; освобождения памяти
    @DosCall; выполнить освобождение памяти
    jnc    end_memfree  ; выход, если не было ошибок
    ; иначе, выйти с установленным
    ; признаком переноса
    mov    word ptr [bp],ax  ; и код ошибки
  ;(в регистре AX)
;
end_memfree:
    pop    ax; восстановить регистр AX
    pop    es
    pop    bp; восстановить  указатель базы
    ret
;
memfree ENDP
;
;
;************************************************************
; Конец стандартной программы
;************************************************************
;
.DATA     ; переключение на сегмент данных
;************************************************************
; Hачало области сохранения данных
;************************************************************
;
; Переменные
;
DiskDrive       db 0    ; рабочий дисковод (начальное
      ; значение = дисковод по умолчанию)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Остальные (из вычисленных) переменные параметров дискового
; формата :
Cylinders    dw   ?   ; общее количество цилиндров
TotalBytes   dd   ?   ; общая емкость диска в байтах
TotalFATSec  dw   ?   ; общее  количество  секторов  таблицы
    ; FAT (всех  копий)
DirEntBytes  dw   32  ; число байтов в элементе каталога
DirSectors   dw   ?   ; сектора, занятые корневым каталогом
DataSectors  dw   ?   ; общее количество секторов для хранения
    ; файлов
ClusterBytes dw   ?   ; количество  байтов  в  кластере
TotalSectors dw   ?   ; общее количество кластеров
FATentryBits db   12  ; количество битов в элементе таблицы FAT
DataBytes    dd   ?   ; общее количество байтов данных (для
    ; хранения файла)
Kbytes       dw   ?   ; общее количество килобайт (всего в
    ; диске)
Mbytes       dw   0   ; общее количество мегабайт (всего в
    ; диске)
Mbytes2      dw   0   ; и общее количество частей в мегабайтах
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Tекстовые сообщения
;
Start1_Msg   db "Идентификатор формата диска операционной"
    db   "системы  MS-DOS"
    db "-- Версия 1.00",CR,LF,"$"
Start2_Msg   db "BPB = Значение, извлеченное из записи"
    db  " начальной загрузки;"
    db "CAL = Вычисленное  значение",CR,LF,CR,LF
    db "Информация о формате для дисковода $"
;
OEM_Msg     db  "BPB: Форматируется при помощи:    $"
SectorBytes_Msg      db  "BPB: Количество байтов в секторе: $"
ClusterSectors_Msg   db  "BPB: Количество секторов в "
   db  "кластере: $"
ReservedSec_Msg      db  "BPB: Зарезервированные сектора:    $"
FATcopies_Msg        db  "BPB: Копии таблицы FAT:   $"
DirEntries_Msg       db  "BPB: Элементы корневого каталога:  $"
TotalSectors_Msg     db  "BPB: Общее количество секторов "
   db  "диска: $"
MediaDescrip_Msg     db  "BPB: Описатель носителя:  $"
FATsectors_Msg       db  "BPB: Сектора  таблицы FAT "
   db  "(1 таблицы FAT):  $"
TrackSectors_Msg     db  "BPB: Общее количество секторов "
   db  "в цилиндре:  $"
Heads_Msg   db  "BPB: Головки:    $"
HiddenSectors_Msg    db  "BPB: Скрытые  секторы:    $"
;
TotalFATsectors_Msg  db  "CAL: Общее количество секторов "
   db  "таблицы FAT: $"
DirSectors_Msg       db  "CAL: Секторы каталога:    $"
Total Bytes_Msg      db  "CAL: Общее количество байтов на"
   db  "диске: $"
Cylinders_Msg        db  "CAL: Общее  количество цилиндров:  $"
DataSectors_Msg      db  "CAL: Общее количество секторов "
   db  "данных:    $"
TotalCluaters_Msg    db  "CAL: Общее количество кластеров:   $"
ClusterBytes_Msg     db  "CAL: Количество байтов в кластере: $"
FATentrySyze_Msg     db  "CAL: Размер элемента таблицы FAT:  $"
DataBytes_Msg        db  "CAL: Общее количество байтов "
   db  "данных:  $"
;
FixedMedia_Msg       db  "(жесткий $"
RemovableMedia_Msg   db  "(сменный $"
Media_Msg   db  "носитель)$"
Bits_Msg    db  "биты$"
Bytes_Msg   db  "байты$"
SmallFAT_Msgdb  "1,5 байта)$"
LargeFAT_Msgdb  "(2 байта)$"
CurrPartition_Msg    db  "(в пределах текущего разделения)$"
PartitionInfo_Msg    db  "(информация о разделении)$"
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Сообщения об ошибках:
NonDOSerr_Msg db "Диск не может быть считан."
     db "Вероятно, это не диск системы DOS.",CR,LF,"$"
BadDrive_Msg  db "синтаксическая ошибка или"
     db "заданный дисковод не разрешен.",CR,LF,"$"
ReadError_Msg db "Общая ошибка при чтении диска."
     db CR,LF,"$"
UnknownErr_Msg db "Неизвестная ошибка - завершение."CR,LF,"$"
;
;
;***********************************************************
; Конец памяти данных
;***********************************************************
 END    main ; конец программы

----------------------------------------------------------------

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz