Mov CR0,EAX ;защита разрешена

; Безусловный дальний переход на метку SetPMode

; (очистить очередь команд и перезагрузить CS)

DB 0EAh

DW (offset SetPMode)

DW SYS_PROT_CS

SetPMode:

; Подготовить границы сегментов

Mov AX,SYS_REAL_SEG

Mov SS,AX

Mov DS,AX

Mov ES,AX

Mov FS,AX

; Снять ограничения с сегмента GS

Mov AX,SYS_MONDO_SEG

Mov GS,AX

; Вернуться в реальный режим

Mov EAX,CR0

And AL,11111110b;сбросить бит PE

Mov CR0,EAX;защита отключена

; Безусловный дальний переход на метку SetRMode

; (очистить очередь команд и перезагрузить CS)

DB 0EAh

DW (offset SetRMode)

Self_Mod_CS DW?

SetRMode:

; Регистры стека и данных

; настроить на сегмент кода

Mov SS,BX

Mov DS,BX

; Обнулить дополнительные сегментные

; регистры данных (GS не трогать!)

Xor AX,AX

Mov ES,AX

Mov FS,AX

; Возврат в реальный режим,

; прерывания снова разрешены

In AL,CMOS_ADDR

And AL,07Fh

Or AL,CH

Out CMOS_ADDR,AL

Popf

Ret

ENDP SetLAddrModeForGS

;****************************************

;* Разрешить работу с памятью выше 1 Мб *

;****************************************

PROC Enable_A20 near

Call Wait8042BufferEmpty

Mov AL,0D1h;команда управления линией A20

Out 64h,AL

Call Wait8042BufferEmpty

Mov AL,0DFh;разрешить работу линии

Out 60h,AL

Call Wait8042BufferEmpty

Ret

ENDP Enable_A20

;***********************************************

;* ОЖИДАНИЕ ОЧИСТКИ ВХОДНОГО БУФЕРА I8042 *

;* При выходе из процедуры: *

;* флаг ZF установлен - нормальное завершение, *

;* флаг ZF сброшен - ошибка тайм-аута. *

;***********************************************

Proc Wait8042BufferEmpty near

Push CX

Mov CX,0FFFFh;задать число циклов

@@kb: in AL,64h;получить статус

Test AL,10b;буфер i8042 свободен?

loopnz @@kb;если нет, то цикл

Pop CX

; (если при выходе сброшен флаг ZF - ошибка)

Ret

Endp Wait8042BufferEmpty

ENDS


ВНИМАНИЕ! Как уже было сказано, после выхода из защищенного режима нельзя перезаписывать регистр GS, иначе будет полностью или частично стерта информация в соответствующем теневом регистре. В частности, нельзя выполнять опе­рации сохранения/восстановления содержимого регистра при помощи команд работы со стеком push и pop.

При использовании нестандартных режимов работы возникают определенные трудности в процессе отладки программ: стандартные программы-отладчики становятся неудобными. Во многих случаях, однако, достаточно использовать про­стую отладочную печать. В листинге 2.2 [1] приведена подпрограмма ShowRegs, ото­бражающая на экране содержимое регистров общего назначения, сегментных ре­гистров, регистра флагов и регистра CR0. Недостаток этого упрощенного примера заключается в том, что ShowRegs не сохраняет содержимое видеопамяти. Однако при использовании линейной адресации программу не трудно усовершенствовать, если есть достаточный запас оперативной памяти: в текстовом режиме для сохра­нения одной страницы нужно менее 4 Кбайт, а в графическом режиме TrueColor32 с разрешением 1920x1280 требуется уже 9,5 Мбайт.

Листинг 2.2 – Отладочная подпрограмма, предназначенная для отображения на экран содержимого регистров процессора


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: