Преобразование из LBA в CHS

Тема в разделе "WASM.BEGINNERS", создана пользователем s3dworld, 21 янв 2011.

  1. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Всем доброго вечера!

    Пишу загрузчик для FAT12. Требуется написать функцию на ассемблере (тут они называются подпрограммами) для преобразования из LBA в CHS.

    Покопавшись по материалам нашёл несколько формул. Вот формула с сайта http://ru.wikipedia.org/wiki/LBA:

    [​IMG]

    А вот с книги Кулакова "Программирование дисковых подсистем":

    [​IMG]

    Интересно получается, формулы то разные. И какая правильная? Лично я доверился Кулакову. Надеюсь я не зря это сделал.

    А вот теперь по поводу реализованной функции. Я сейчас Вам её покажу и хочу в ответ услышать советы по коду.

    Код (Text):
    1. ; -------------------------------------------------------------------------------------
    2. ; Формат:     bool GetCHSFromLBA(
    3. ;                                   unsigned short int _index,
    4. ;                                   unsigned short int* _cylinder,
    5. ;                                   unsigned short int* _head,
    6. ;                                   unsigned short int* _sector);
    7. ; Описание:     Преобразование из LBA в CHS
    8. ; Параметры:   _index      - индекс сектора в системе LBA
    9. ;               _cylinder   - номер цилиндра в системе CHS
    10. ;               _head       - номер головки в системе CHS
    11. ;               _sector     - номер сектора в системе CHS
    12. ; Результат:   При успешном завершении возвращает true, в противном случае - false
    13. ; -------------------------------------------------------------------------------------
    14. GetCHSFromLBA:
    15.     push BP
    16.     mov BP,SP
    17.    
    18.     ; Проверяем не является ли _cylinder нулевым указателем
    19.     mov AX,[BP+6]
    20.     test AX,AX
    21.     jz _getCHSFromLBA_ExitFalse
    22.    
    23.     ; Проверяем не является ли _head нулевым указателем
    24.     mov AX,[BP+8]
    25.     test AX,AX
    26.     jz _getCHSFromLBA_ExitFalse
    27.    
    28.     ; Проверяем не является ли _sector нулевым указателем
    29.     mov AX,[BP+10]
    30.     test AX,AX
    31.     jz _getCHSFromLBA_ExitFalse
    32.    
    33.     ; Находим цилиндр
    34.     mov AX,[BPB_NumHeads]
    35.     mul [BPB_TotSec16]
    36.     mov BX,AX
    37.     mov AX,[BP+4]
    38.     div BX
    39.     mov [BP+6],BX
    40.     mov [BX],AX
    41.    
    42.     ; Находим головку
    43.     mov BX,[BP+6]
    44.     mov AX,[BX]
    45.     mov BX,[BPB_NumHeads]
    46.     mul BX
    47.     mov BX,[BPB_TotSec16]
    48.     mul BX
    49.     mov BX,[BP+4]
    50.     sub BX,AX
    51.     mov AX,BX
    52.     mov BX,[BPB_TotSec16]
    53.     div BX
    54.     mov BX,[BP+8]
    55.     mov [BX],AX
    56.    
    57.     ; Находим сектор
    58.     mov BX,[BP+6]
    59.     mov AX,[BX]
    60.     mov BX,[BPB_NumHeads]
    61.     mul BX
    62.     mov BX,[BP+8]
    63.     mov CX,[BX]
    64.     add AX,CX
    65.     mov BX,[BPB_TotSec16]
    66.     mul BX
    67.     mov BX,AX
    68.     mov AX,[BP+4]
    69.     sub AX,BX
    70.     inc AX
    71.     mov BX,[BP+10]
    72.     mov [BX],AX
    73.    
    74.     jmp _getCHSFromLBA_ExitTrue
    75.    
    76. _getCHSFromLBA_ExitFalse:
    77.     mov AX,0
    78.     jmp _getCHSFromLBA_Exit
    79.    
    80. _getCHSFromLBA_ExitTrue:
    81.     mov AX,1
    82.    
    83. _getCHSFromLBA_Exit:
    84.     mov SP,BP
    85.     pop BP
    86. ret
     
  2. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    тут еще не разбираюсь, но этот алго можно обратить, думаю:
    http://fool.asm4u.net/

    папка \fool\boot\
     
  3. abcd008

    abcd008 New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2009
    Сообщения:
    616
    вот правильная формула:
    S = N mod SPT + 1
    T = N / SPT

    H = T mod Heads
    C = T / Heads

    если не дурак реализуется при помощи двух делений:)
     
  4. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    abcd008
    Да правильную формулу я уже нашёл, она у Кулакова была. Я сначала подумал что она не правильная и начал свою составлять. Но когда свою начал составлять, до меня дошло что я просто не тот параметр подставлял в формуле Кулакова. Так что всё исправил и теперь у меня нормальный вариант. Ну а по формулам выше, что такое SPT?
     
  5. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Да и не понимаю что тут за T такое?
     
  6. abcd008

    abcd008 New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2009
    Сообщения:
    616
    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 что точно правильнее.
     
  7. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    abcd008
    Спасибо))
     
  8. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    abcd008
    Вот так вот я это дело оформил:

    Код (Text):
    1. ; -------------------------------------------------------------------------------------
    2. ; Формат:       void GetCHSFromLBA(
    3. ;                                   unsigned short int _index,
    4. ;                                   unsigned short int* _cylinder,
    5. ;                                   unsigned short int* _head,
    6. ;                                   unsigned short int* _sector);
    7. ; Описание:     Преобразование из LBA в CHS
    8. ; Параметры:    _index      - индекс сектора в системе LBA
    9. ;               _cylinder   - номер цилиндра в системе CHS
    10. ;               _head       - номер головки в системе CHS
    11. ;               _sector     - номер сектора в системе CHS
    12. ; -------------------------------------------------------------------------------------
    13. GetCHSFromLBA:
    14.     ; unsigned short int    [BP-2]  // локальная переменная функции
    15.     ;                       [BP]    // старое значение BP
    16.     ;                       [BP+2]  // адрес возврата
    17.     ;                       [BP+4]  // _index
    18.     ;                       [BP+6]  // _cylinder
    19.     ;                       [BP+8]  // _head
    20.     ;                       [BP+10] // _sector
    21.  
    22.     push BP
    23.     mov BP,SP
    24.  
    25.     ; Находим значение локальной переменной функции
    26.     mov AX,[BP+4]
    27.     mov BX,[BPB_SecPerTrk]
    28.     div BX
    29.     mov [BP-2],AX
    30.  
    31.     ; Находим цилиндр
    32.     mov BX,[BPB_NumHeads]
    33.     div BX
    34.     mov [BP+6],AX
    35.  
    36.     ; Находим головку
    37.     mov AX,[BP-2]
    38.     div BX
    39.     mov [BP+8],DX
    40.  
    41.     ; Находим сектор
    42.     mov AX,[BP+4]
    43.     mov BX,[BPB_SecPerTrk]
    44.     div BX
    45.     inc DX
    46.     mov [BP+10],DX
    47.  
    48.     mov SP,BP
    49.     pop BP
    50. ret