Пишем свой загрузочный сектор
Страница 2. Загрузка файла в память


Загрузка файла в память 

Если файл найден, то загрузим его в память и передадим управление на его начало.

Found:
; Загрузка загрузчика (извените, калабур)
movbx, SETUP_ADDR
movax, [byte di+DIR_FstClusLow]; Номер первого кластера файла
; Загружаем сектор с элемнтами FAT, среди которых есть FAT[ax]
; LoadFAT сохраняет значения всех регистров
callLoadFAT
ReadCluster:
; ax - Номер очередного кластера
; Загрузим его в память
pushax
; Первые два элемента FAT служебные
decax
decax
; Число секторов для чтения
; cx = 0 после ReadSectors
movcl, [byte bp+BPB_SecPerClus]; Секторов на кластер
mulcx
; dx:ax - Смещение кластера относительно области данных
addax, [byte bp+SysSize]
adcdx, [byte bp+SysSize+2]
; dx:ax - Номер первого сектора требуемого кластера
; cx еще хранит количество секторов на кластер
; es:bx - конец прошлого кластера и начало нового
callReadSectors; читаем кластер
jcnear DiskError; Увы, ошибка чтения
popax; Номер кластера
; Это конец файла?
; Получим значение следующего элемента FAT
pusha
; Вычислим адрес элемента FAT
movbx, ax
shlax, 1
addax, bx
shrax, 1
; Получим номер сектора, в котором находится текущий элемент FAT
cwd
divword [byte bp+BPB_BytsPerSec]
cmpax, [bp+fat]; Мы уже читали этот сектор?
popa
jeChecked; Да, читали
; Нет, надо загрузить этот сектор
callLoadFAT
Checked:
; Вычислим адрес элемента FAT в буфере
pushbx
movbx, ax
shlbx, 1
addbx, ax
shrbx, 1
andbx, 511; остаток от деления на 512
movbx, [bx+0x700]; а вот и адрес
; Извлечем следующий элемент FAT
; В FAT16 и FAT32 все немного проще :(
testal, 1
jnzodd
andbx, 0xFFF
jmpshort done
odd:
shrbx, 4
done:
movax, bx
popbx
; bx - новый элемент FAT
cmpax, 0xFF8; EOF - конец файла?
jbReadCluster; Нет, читаем следующий кластер
; Наконец-то загрузили
movax, SETUP_ADDR>>4; SETUP_SEG
moves, ax
movds, ax
; Передаем управление, наше дело сделано :)
jmpSETUP_ADDR>>4:0

LoadFAT;proc
; Процедура для загрузки сектора с элементами FAT
; Элемент ax должен находится в этом секторе
; Процедура не должна менять никаких регистров
pusha
; Вычисляем адрес слова содержащего нужный элемент
movbx, ax
shlax, 1
addax, bx
shrax, 1
cwd
divword [byte bp+BPB_BytsPerSec]
; ax - смещение сектора относительно начала таблицы FAT
mov[bp+fat], ax; Запомним это смещение, dx = 0
cwd; dx:ax - номер сектора, содержащего FAT[?]
; Добавим смещение к первой копии таблицы FAT
addax, [byte bp+BPB_RsvdSecCnt]
adcdx, 0
addax, [byte bp+BPB_HiddSec]
adcdx, [byte bp+BPB_HiddSec+2]
movcx, 1; Читаем один сектор. Можно было бы и больше, но не быстрее
movbx, 700h; Адрес буфера
callReadSectors
jcDiskError; Ошибочка вышла
popa
ret
;LoadFATendp

В FAT12 на каждый элемент FAT отводится по 12 бит, что несколько усложняет нашу работу, в FAT16 и FAT32 на каждый элемент отводится по 16 и 32 бита соответственно и можно просто прочесть слово или двойное слово, а в FAT12 необходимо прочесть слово содержащее элемент FAT и правильно извлечь из него 12 бит.

 
« Предыдущая статья   Следующая статья »