Можно ли использовать 32-битные регистры / инструкции в реальном режиме?

Я запутался в простой задаче сборки при изучении простого исходного кода для ОС.

На этом сайте: http://wiki.osdev.org/Babystep7 следующий код предназначен для перехода из реального режима в защищенный режим.

mov  eax, cr0
or al,1
mov  cr0, eax

Я знаю, как перейти из реального режима в защищенный режим.
Но мой вопрос: поскольку программа все еще находится в реальном режиме, как она может использовать 32-битные регистры или инструкции?

Можно ли использовать 32-битные регистры / инструкции в реальном режиме?

6 ответов

Решение

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

Существует префикс "переопределение размера операнда" (66h), который изменяет режим по умолчанию для отдельной инструкции. Когда этот префикс используется с инструкцией, выполняемой в 16-битном реальном режиме, он переключит инструкцию на 32-битную. И наоборот, когда этот префикс используется с инструкцией, выполняемой в 32-битном защищенном режиме, он переключит инструкцию на 16-битную. (Аналогичный префикс, 67h, работает для переопределения размеров адресов.)

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

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

Насколько я понимаю, реальный режим не влияет на команды, которые вы можете запускать на ЦП, но влияет на то, как интерпретируются эталонные команды памяти ЦП.

Так что да, вы можете использовать eax, но вы не сможете получить [eax] ячейка памяти.

См. Соответствующую часть в руководстве Intel.

Существует 32-битный реальный режим, он называется нереальным. В те времена он использовался для получения доступа ко всему адресному пространству без хлопот с использованием селекторов и накладных расходов всего защищенного режима.

Для простой адресации префикс операнда и размера инструкции работал очень хорошо. 16-разрядное приложение защищенного (изначально реального) режима, которое я когда-то писал для Windows (3.1 и более поздние версии для 9x), могло выделять> 64 КБ областей памяти, используя API памяти Windows, и вопрос заключался в том, как его использовать. В любом случае, используя (дальний) указатель указателя и упомянутые префиксы, мое приложение хорошо использовало области 40 МБ, даже если оно работало в 16-битном режиме.

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

Возможно, вы можете использовать код операции LoadAll 0F07h, который дает вам 32-битный доступ в 16-битном реальном режиме.

Насколько я знаю, в реальном режиме нельзя использовать 32-битные регистры. В 32-битном регистре управления CR0 реальный режим и защищенный режим определяются путем просмотра первого бита CR0 (PE). В этом коде вы меняете PE в последней строке (mov cr0,eax). Я думаю, после этой строки вы не можете больше использовать 32-битные ссылки на регистры.

Другие вопросы по тегам