Иллюстрированный самоучитель по Assembler


Основы защищенного режима - часть 21


Если мы просто перейдем в реальный режим сбросом бита 0 в регистре CR0, то в теневых регистрах останутся дескрипторы защищенного режима и при первом же обращении к любому сегменту программы возникнет исключение общей защиты, так как ни один из наших сегментов не имеет границы, равной FFFFh. Поскольку мы не обрабатываем исключения, произойдет либо сброс процессора и перезагрузка компьютера, либо зависание. Таким образом, перед переходом в реальный режим необходимо исправить дескрипторы всех наших сегментов: команд, данных, стека и видеобуфера К сегментным регистрам FS и GS мы не обращались, и о них можно не заботиться.

Теневые регистры, куда, собственно, надо записать значение границы, нам недоступны. Для из модификации придется прибегнуть к окольному маневру: записать в поля границ всех четырех дескрипторов значение FFFFh, а затем повторно загрузить селекторы в сегментные регистры, что приведет к перезаписи содержимого теневых регистров. С сегментным регистром CS так поступить нельзя, поэтому его загрузку придется выполнить, как и ранее, с помощью искусственно сформированной команды дальнего перехода.

Настроив все использовавшиеся в программе сегментные регистры, можно сбросить бит 0 в CR0. После перехода в реальный режим нам придется еще раз выполнить команду дальнего перехода, чтобы очистить очередь команд в блоке предвыборки и загрузить в регистр CS вместо хранящегося там селектора обычный сегментный адрес регистра команд.

Теперь процессор снова работает в реальном режиме, причем, хотя в сегментных регистрах DS, ES и SS остались незаконные для реального режима селекторы, программа будет какое-то время выполняться правильно, так как в теневых регистрах находятся правильные линейные адреса (оставшиеся от защищенного режима) и законные для реального режима границы (загруженные туда нами). Если, однако, в программе встретятся команды сохранения и восстановления содержимого сегментных регистров, например

push DS

...

pop DS

выполнение программы будет нарушено, так как команда pop DS загрузит в DS не сегментный адрес реального режима, а селектор, т.е. число 8 в нашем случае. Это число будет рассматриваться процессором, как сегментный адрес, и дальнейшие обращения к полям данных приведут к адресации физической памяти начиная с абсолютного адреса 80h, что, конечно, лишено смысла. Даже если в нашей программе нет строк сохранения и восстановления сегментных регистров, они неминуемо встретятся, как только произойдет переход в DOS по команде int 21h, так как диспетчер DOS сохраняет, а затем восстанавливает все регистры задачи, в том числе и сегментные. Поэтому после перехода в реальный режим необходимо загрузить в используемые далее сегментные регистры соответствующие сегментные адреса, что и выполняется в программе для регистров DS и SS. Надо также не забыть разрешить запрещенные нами ранее аппаратные прерывания (команда sti).




Начало  Назад  Вперед



Книжный магазин