Смешивание 32-битного и 16-битного кода с насм

Это системный вопрос низкого уровня.

Мне нужно смешать 32-битный и 16-битный код, потому что я пытаюсь вернуться в реальный режим из защищенного режима. Как часть справочной информации, мой код делает это сразу после загрузки GRUB, поэтому у меня нет какой-либо надоедливой операционной системы, чтобы сказать мне, что я могу и не могу сделать.

В любом случае, я использую [BITS 32] и [BITS 16] со своей сборкой, чтобы сказать nasm, какие типы операций он должен использовать, но когда я тестирую свой код, используйте bochs, похоже, что для некоторых операций bochs не выполняет код, который Я написал. Похоже, что ассемблер придерживается дополнительных функций, 0x66и 0x67это сбивает с толку bochs.

Итак, как мне получить nasm для успешной сборки кода, где я смешиваю 32-битный и 16-битный код в одном файле? Есть ли какая-то хитрость?

20.08.2008 16:30:52
4 ОТВЕТА

Вы не шутили, что это низкий уровень!

Вы проверили сгенерированные коды операций / операнды, чтобы убедиться, что nasm правильно выполняет ваши директивы BITS? Также проверьте, чтобы убедиться, что цели прыжка правильные - возможно, нос использует неправильные смещения.

Если это не ошибка в nasm, возможно, есть ошибка в bochs. Я не могу себе представить, что люди часто переключаются обратно в 16-битный режим из 32-битного режима.

0
20.08.2008 16:50:47

0x66 и 0x67 - это коды операций, которые используются для указания того, что следующий код операции должен интерпретироваться как битность не по умолчанию. Более конкретно (и по этой ссылке )

«Когда NASM находится в режиме BITS 16, инструкции, в которых используются 32-разрядные данные, имеют префикс 0x66, а те, которые ссылаются на 32-разрядные адреса, имеют префикс 0x67. В режиме BITS 32 верно обратное: 32-разрядные инструкции не требуют префиксов, в то время как инструкции, использующие 16-битные данные, требуют 0x66, а те, которые работают с 16-битными адресами, требуют 0x67. "

Это говорит о том, что это Бохс, что виноват.

4
20.08.2008 16:54:09

Если вы находитесь в реальном режиме, ваш размер по умолчанию неявно равен 16 битам, поэтому вы должны использовать режим BITS 16. Таким образом, если вам нужен 32-битный размер операнда, вы добавляете префикс 0x66, а для 32-битного размера адреса вы добавляете префикс 0x67.

Посмотрите Руководство разработчика программного обеспечения Intel IA-32, том 3, глава 16 (СМЕШИВАНИЕ 16-БИТОВОГО И 32-БИТОВОГО КОДА; номер главы может измениться в зависимости от издания книги):

Режим реального адреса, режим virtual-8086 и SMM являются собственными 16-разрядными режимами.

Директива BITS 32 будет сбивать с толку ассемблера только в том случае, если вы используете ее вне защищенного режима или в длинном режиме.

0
20.08.2008 17:30:46

Проблема оказалась в том, что я неправильно настраивал свои таблицы дескрипторов. У меня один бит перевернулся неправильно, поэтому вместо перехода в 16-битный режим я перешел в 32-битный режим (с сегментами, у которых было ограничение в один мегабайт).

Спасибо за предложения!

Терри

6
21.08.2008 14:43:15