Системное программное обеспечение. Особенности программирования 32-разрядных процессоров. Рощин А.В. - 53 стр.

UptoLike

Составители: 

53
; Сохранить регистр флагов
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
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
; Обнулить дополнительные сегментные
; Сохранить регистр флагов
        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
        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
        ; Обнулить дополнительные сегментные


                            53