Всем доброго вечера! Пишу загрузчик для FAT12. Требуется написать функцию на ассемблере (тут они называются подпрограммами) для преобразования из LBA в CHS. Покопавшись по материалам нашёл несколько формул. Вот формула с сайта http://ru.wikipedia.org/wiki/LBA: А вот с книги Кулакова "Программирование дисковых подсистем": Интересно получается, формулы то разные. И какая правильная? Лично я доверился Кулакову. Надеюсь я не зря это сделал. А вот теперь по поводу реализованной функции. Я сейчас Вам её покажу и хочу в ответ услышать советы по коду. Код (Text): ; ------------------------------------------------------------------------------------- ; Формат: bool GetCHSFromLBA( ; unsigned short int _index, ; unsigned short int* _cylinder, ; unsigned short int* _head, ; unsigned short int* _sector); ; Описание: Преобразование из LBA в CHS ; Параметры: _index - индекс сектора в системе LBA ; _cylinder - номер цилиндра в системе CHS ; _head - номер головки в системе CHS ; _sector - номер сектора в системе CHS ; Результат: При успешном завершении возвращает true, в противном случае - false ; ------------------------------------------------------------------------------------- GetCHSFromLBA: push BP mov BP,SP ; Проверяем не является ли _cylinder нулевым указателем mov AX,[BP+6] test AX,AX jz _getCHSFromLBA_ExitFalse ; Проверяем не является ли _head нулевым указателем mov AX,[BP+8] test AX,AX jz _getCHSFromLBA_ExitFalse ; Проверяем не является ли _sector нулевым указателем mov AX,[BP+10] test AX,AX jz _getCHSFromLBA_ExitFalse ; Находим цилиндр mov AX,[BPB_NumHeads] mul [BPB_TotSec16] mov BX,AX mov AX,[BP+4] div BX mov [BP+6],BX mov [BX],AX ; Находим головку mov BX,[BP+6] mov AX,[BX] mov BX,[BPB_NumHeads] mul BX mov BX,[BPB_TotSec16] mul BX mov BX,[BP+4] sub BX,AX mov AX,BX mov BX,[BPB_TotSec16] div BX mov BX,[BP+8] mov [BX],AX ; Находим сектор mov BX,[BP+6] mov AX,[BX] mov BX,[BPB_NumHeads] mul BX mov BX,[BP+8] mov CX,[BX] add AX,CX mov BX,[BPB_TotSec16] mul BX mov BX,AX mov AX,[BP+4] sub AX,BX inc AX mov BX,[BP+10] mov [BX],AX jmp _getCHSFromLBA_ExitTrue _getCHSFromLBA_ExitFalse: mov AX,0 jmp _getCHSFromLBA_Exit _getCHSFromLBA_ExitTrue: mov AX,1 _getCHSFromLBA_Exit: mov SP,BP pop BP ret
вот правильная формула: S = N mod SPT + 1 T = N / SPT H = T mod Heads C = T / Heads если не дурак реализуется при помощи двух делений
abcd008 Да правильную формулу я уже нашёл, она у Кулакова была. Я сначала подумал что она не правильная и начал свою составлять. Но когда свою начал составлять, до меня дошло что я просто не тот параметр подставлял в формуле Кулакова. Так что всё исправил и теперь у меня нормальный вариант. Ну а по формулам выше, что такое SPT?
S = N mod SPT + 1 T = N / SPT H = T mod Heads C = T / Heads преобразуй и получишь: S = N mod SPT + 1 H = N / SPT mod Heads C = N / SPT / Heads где C-цылиндр H-головка S-сектор N-LBA адрес из которого ты преобразуешь SPT-максимальное число секторов(на дорожке) HEAD-максилальное количество головок и эта формула быстрее и проще чем у Кулакова я сам сначала Кулаковскую пробовал, но эта написана в спецификации ATA-1 что точно правильнее.
abcd008 Вот так вот я это дело оформил: Код (Text): ; ------------------------------------------------------------------------------------- ; Формат: void GetCHSFromLBA( ; unsigned short int _index, ; unsigned short int* _cylinder, ; unsigned short int* _head, ; unsigned short int* _sector); ; Описание: Преобразование из LBA в CHS ; Параметры: _index - индекс сектора в системе LBA ; _cylinder - номер цилиндра в системе CHS ; _head - номер головки в системе CHS ; _sector - номер сектора в системе CHS ; ------------------------------------------------------------------------------------- GetCHSFromLBA: ; unsigned short int [BP-2] // локальная переменная функции ; [BP] // старое значение BP ; [BP+2] // адрес возврата ; [BP+4] // _index ; [BP+6] // _cylinder ; [BP+8] // _head ; [BP+10] // _sector push BP mov BP,SP ; Находим значение локальной переменной функции mov AX,[BP+4] mov BX,[BPB_SecPerTrk] div BX mov [BP-2],AX ; Находим цилиндр mov BX,[BPB_NumHeads] div BX mov [BP+6],AX ; Находим головку mov AX,[BP-2] div BX mov [BP+8],DX ; Находим сектор mov AX,[BP+4] mov BX,[BPB_SecPerTrk] div BX inc DX mov [BP+10],DX mov SP,BP pop BP ret