CMOS_DATA equ 0071h
; Селекторы сегментов
SYS_PROT_CS equ 0008h
SYS_REAL_SEG equ 0010h
SYS_MONDO_SEG equ 0018h
CODESEG
;**********************************************
;* ВКЛЮЧЕНИЕ РЕЖИМА ЛИНЕЙНОЙ АДРЕСАЦИИ ПАМЯТИ *
;* (процедура параметров не имеет) *
;**********************************************
PROC Initialization NEAR
Pushad
; Сохранить значения сегментных регистров в
; реальном режиме (кроме GS)
mov [CS:Save_SP],SP
Mov AX,SS
mov [CS:Save_SS],AX
Mov AX,DS
mov [CS:Save_DS],AX
; (работаем теперь только с кодовым сегментом)
Mov AX,CS
mov [word ptr CS:Self_Mod_CS],AX
Mov DS,AX
Cli
Mov SS,AX
Mov SP,offset Local_Stk_Top
Sti
; Установить режим линейной адресации
Call SetLAddrModeForGS
; Восстановить значения сегментных регистров
Cli
mov SP,[CS:Save_SP]
mov AX,[CS:Save_SS]
Mov SS,AX
mov AX,[CS:Save_DS]
Mov DS,AX
Sti
; Разрешить работу линии A20
Call Enable_A20
Popad
Ret
ENDP Initialization
; Область сохранения значений сегментных регистров
Save_SP DW?
Save_SS DW?
Save_DS DW?
; Указатель на GDT
GDTPtr DQ?
; Таблица дескрипторов сегментов для
; входа в защищенный режим
|
|
GDT DW 00000h,00000h,00000h,00000h;не используется
DW 0FFFFh,00000h,09A00h,00000h;сегмент кода CS
DW 0FFFFh,00000h,09200h,00000h;сегмент данных DS
DW 0FFFFh,00000h,09200h,0008Fh;сегмент GS
; Локальный стек для защищенного режима
; (организован внутри кодового сегмента)
Label GDTEnd word
DB 255 DUP(0FFh)
Local_Stk_Top DB (0FFh)
;*********************************************
;* ОТМЕНИТЬ ПРЕДЕЛ СЕГМЕНТА GS *
;* Процедура изменяет содержимое теневого *
;* регистра GS таким образом, что становится *
;* возможной линейная адресация через него *
;* 4 Gb памяти в реальном режиме *
;*********************************************
PROC SetLAddrModeForGS near
; Вычислить линейный адрес кодового сегмента
Mov AX,CS
Movzx EAX,AX
Shl EAX,4;умножить номер параграфа на 16
Mov EBX,EAX;сохранить линейный адрес в EBX
; Занести младшее слово линейного адреса в дескрипторы
; сегментов кода и данных
mov [word ptr CS:GDT+10],AX
mov [word ptr CS:GDT+18],AX
; Переставить местами старшее и младшее слова
Ror EAX,16
; Занести биты 16-23 линейного адреса в дескрипторы
; сегментов кода и данных
mov [byte ptr CS:GDT+12],AL
mov [byte ptr CS:GDT+20],AL
; Установить предел (Limit) и базу (Base) для GDTR
lea ax,[GDT];*************
movzx eax,ax;*************
Add EBX,EAX; offset GDT
mov [word ptr CS:GDTPtr],(offset GDTEnd-GDT-1)
mov [dword ptr CS:GDTPtr+2],EBX
; Сохранить регистр флагов
Pushf
; Запретить прерывания, так как таблица прерываний IDT
; не сформирована для защищенного режима
Cli
; Запретить немаскируемые прерывания NMI
In AL,CMOS_ADDR
Mov AH,AL
Or AL,080h;установить старший разряд
Out CMOS_ADDR,AL;не затрагивая остальные
And AH,080h
; Запомнить старое состояние маски NMI
Mov CH,AH
; Перейти в защищенный режим
lgdt [fword ptr CS:GDTPtr]
Mov BX,CS;запомнить сегмент кода
|
|
Mov EAX,CR0
Or AL,01b;установить бит PE