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


5

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

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

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

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

0

Вы не шутите об этом на низком уровне!

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

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


3

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

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

Это говорит о том, что это бочи, что при вине.


0

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

Посмотрите на руководстве Intel IA-32 программного обеспечения разработчика, Том 3, глава 16 (СМЕСИТЕЛЬНОЕ 16-битный и 32-битный код, номер главы может меняться в зависимости от издания книги):

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

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


6

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

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

Terry

+1

Подсказка: примите ваш ответ, когда это произойдет. 17 мар. 102010-03-17 21:13:07