Длинный переход в загрузчике на fasm

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

  1. Vizvamitra

    Vizvamitra New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    3
    Здравствуйте. Дело такое: решил написать загрузчик. Умею пока мало, врубался на ходу, читая эту статью: http://www.realcoding.net/article/view/2205 .
    В ней дело начинается с копирования кода загрузчика из 7с00h в 0600h, после чего происходит длинный переход на метку go:
    Код (Text):
    1. ...
    2. repnz movsw ; это он копирует весь первый сектор, как я писал выше
    3. jmpi go, #0
    4. go:         ; сюда, но уже по адресу 600:go должен быть выполнен переход
    5. ...
    так вот. Фасм jmpi не знает, пишу jmp far 600h:go, но это не работает, в том смысле, что bochs мне пишет "LOCK prefix unallowed (op1=0x3e, attr=0x40b mod =0x0 nnn=0)" кучу раз и ничего не происходит. Вопрос: в чём причина? Не хочет менять значение cs? или я с чужого синтаксиса не правильно перевёл? (я пока знаком только с базовым универским курсом тасма, и то только 1 семестр, так что палками не тыкать, если глупость где написал. Я уже задолбался искать через гугл информацию, решил вас спросить)
     
  2. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    он у тебя прыгает не на код а на мусор судя по сообщению об ошибке.
    проверяй действительно ли копируется код куда надо и правильный ли адрес перехода?
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Vizvamitra
    jmpi вообще мало кто знает. Перевод, разумеется, неправильный. Прыгнуть по линейному адресу 600h (логическому 0:600h) — это совсем не то же, что прыгнуть по логическому адресу 600h:0 (который соответствует линейному 6000h). Соответственно, 600h:go — это не то же, что 600h+go. Формально прыжок должен быть следующего вида:
    Код (Text):
    1. jmp far 0:(600h+go-$$)
    2. go:
    А можно сделать и так:
    Код (Text):
    1. jmp far 0:go
    2. org ($-$$)+600h
    3. go:
    Модификатор типа прыжка far в данных случаях не обязателен.
    P.S. $$ равен предполагаемой базе текущего куска кода (для бинарных файлов равен аргументу последней предшествующей директивы org), а $ равен предполагаемому адресу текущей инструкции.
    P.P.S. Упомянутая статья, кстати, не без ошибок.
     
  4. Vizvamitra

    Vizvamitra New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    3
    l_inc, ага, спасибо. но, насколько я понимаю, нужно, чтобы при переходе изменился cs, причём чтобы стал 600h. В предложенном варианте это произойдёт?
     
  5. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Vizvamitra
    Ну чтобы cs стал равным 600h, Вам точно не нужно. Как я уже объяснил, если cs станет 600h, то назначение прыжка будет по cs:go = 600h:go, что соответствует линейному адресу 6000h+go, а не 600h+go, где на самом деле находится метка в скопированном коде.
    Нет. Этого не произойдёт. Но на самом деле в этом нет необходимости и определяется только предпочтениями автора. Если Вашим предпочтениям соответствует исполнение по нулевому смещению (логического адреса), то для осуществления прыжка по линейному адресу 600h+go нужно писать соответственно:
    Код (Text):
    1. jmp far 60h:go-$$
    2. go:
    или несколько более корректный вариант:
    Код (Text):
    1. jmp far 60h:go
    2. org $-$$
    3. go:
    В этом случае в cs попадёт 60h, в ip адрес метки go, а исполнение продолжится по линейному адресу 600h+go.
     
  6. Vizvamitra

    Vizvamitra New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    3
    l_inc, Спасибо, в общем. За ещё 4 часа медитаций я-таки победил его) А там дело было в косяках с адресами меток. И я, чёрт, теперь наизусть знаю, как это всё работает и что зачем там)