Здравствуйте. Дело такое: решил написать загрузчик. Умею пока мало, врубался на ходу, читая эту статью: http://www.realcoding.net/article/view/2205 . В ней дело начинается с копирования кода загрузчика из 7с00h в 0600h, после чего происходит длинный переход на метку go: Код (Text): ... repnz movsw ; это он копирует весь первый сектор, как я писал выше jmpi go, #0 go: ; сюда, но уже по адресу 600:go должен быть выполнен переход ... так вот. Фасм jmpi не знает, пишу jmp far 600h:go, но это не работает, в том смысле, что bochs мне пишет "LOCK prefix unallowed (op1=0x3e, attr=0x40b mod =0x0 nnn=0)" кучу раз и ничего не происходит. Вопрос: в чём причина? Не хочет менять значение cs? или я с чужого синтаксиса не правильно перевёл? (я пока знаком только с базовым универским курсом тасма, и то только 1 семестр, так что палками не тыкать, если глупость где написал. Я уже задолбался искать через гугл информацию, решил вас спросить)
он у тебя прыгает не на код а на мусор судя по сообщению об ошибке. проверяй действительно ли копируется код куда надо и правильный ли адрес перехода?
Vizvamitra jmpi вообще мало кто знает. Перевод, разумеется, неправильный. Прыгнуть по линейному адресу 600h (логическому 0:600h) — это совсем не то же, что прыгнуть по логическому адресу 600h:0 (который соответствует линейному 6000h). Соответственно, 600h:go — это не то же, что 600h+go. Формально прыжок должен быть следующего вида: Код (Text): jmp far 0:(600h+go-$$) go: А можно сделать и так: Код (Text): jmp far 0:go org ($-$$)+600h go: Модификатор типа прыжка far в данных случаях не обязателен. P.S. $$ равен предполагаемой базе текущего куска кода (для бинарных файлов равен аргументу последней предшествующей директивы org), а $ равен предполагаемому адресу текущей инструкции. P.P.S. Упомянутая статья, кстати, не без ошибок.
l_inc, ага, спасибо. но, насколько я понимаю, нужно, чтобы при переходе изменился cs, причём чтобы стал 600h. В предложенном варианте это произойдёт?
Vizvamitra Ну чтобы cs стал равным 600h, Вам точно не нужно. Как я уже объяснил, если cs станет 600h, то назначение прыжка будет по cs:go = 600h:go, что соответствует линейному адресу 6000h+go, а не 600h+go, где на самом деле находится метка в скопированном коде. Нет. Этого не произойдёт. Но на самом деле в этом нет необходимости и определяется только предпочтениями автора. Если Вашим предпочтениям соответствует исполнение по нулевому смещению (логического адреса), то для осуществления прыжка по линейному адресу 600h+go нужно писать соответственно: Код (Text): jmp far 60h:go-$$ go: или несколько более корректный вариант: Код (Text): jmp far 60h:go org $-$$ go: В этом случае в cs попадёт 60h, в ip адрес метки go, а исполнение продолжится по линейному адресу 600h+go.
l_inc, Спасибо, в общем. За ещё 4 часа медитаций я-таки победил его) А там дело было в косяках с адресами меток. И я, чёрт, теперь наизусть знаю, как это всё работает и что зачем там)