Можно ли использовать 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-битные ссылки на регистры.