CMOS_ADDR equ 0070h

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


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



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