mov dl, ah

shr dl, 4

shl ax, 4

; Устанавливаем адрес сегмента стека ;

в глобальной таблице дескрипторов

mov bx, offset gdt_ss

setgdtentry

; Перехватываем рестарт.

pushds

mov ax, 40h

mov ds, ax

mov word ptr ds:[0067h], offset shutdown_return

mov word ptr ds:[0069h], cs

pop ds

; Запрещаем маскируемые прерывания

cli

in al, INT_MASK_PORT

or al, OFFh

out INT_MASK_PORT, al

mov al, 8Fh

out CMOS_PORT, al

jmp $+2 mov al, 5

out CMOS_PORT+1, al

ret

init_protected_mode ENDP

; Подпрограмма, переводящая процессор в защищенный режим

set_protected_mode PROC

; Открываем адресную линию А20 для доступа свыше 1 Мбайт

call enable_a20

; Сохранение значения регистра SS для реального режима

mov real_ss, ss

; Перевод компилятора Turbo Assembler в улучшенный режим.

; IDEAL – это не команда и не оператор, это директива, влияющая

; только на интерпретацию дальнейших строк листинга

ideal

р286

;Загружаем регистр глобальной таблицы дескрипторов GDTR

lgdt[QWORD gdt_gdt] ; db OFh,01h,16h dw offset gdt_gdt ;

Переводим процессор в защищенный режим

mov ax, 0001h

lmswax ; db OFh,01h,FOh

; Переводим компилятор Turbo Assembler назад в режим MASM

masm

.286

jmp far flush

; db 0EAh

; dw offset flush

; dw CS_DESCR

flush:

; Останавливаем в регистр SS селектор сегмента стека

mov ax, SS_DESCR

mov ss, ax

; Устанавливаем в регистр DS селектор сегмента данных

mov ax, DS_DESCR

mov ds, ax

; Записываем в строку qw символ 'L' и выходим из подпрограммы

mov byte ptr ds:[offset qw+2],'L'

ret

set_protected_mode ENDP

; Подпрограмма, возвращающая процессор в реальный режим

set_real_mode PROC

; Сохраняем значение регистра SP для реального режима

mov real_sp, sp

; Выполняем CPU Reset (рестарт процессора)

mov al, SHUT_DOWN

out STATUS_PORT, al

; Ждем, пока процессор перезапустится

wait_reset:

hlt

jmp wait_reset

; C этого места программа выполняется после перезапуска процессора

shutdown_return:

; Устанавливаем регистр DS в соответствии с регистром CS

pushcs

pop ds

; Восстанавливаем указатели на стек

; по ранее сохраненным значениям

mov ss, real_ss

mov sp, real_sp

; Закрываем адресную линию А20

call disable_a20

; Разрешаем немаскируемые прерывания

mov ax, 000dh

out CMOS_PORT, al

; Разрешаем маскируемые прерывания

in al, INT_MASK_PORT

and al, 0

out INT_MASK_PORT, al

sti

ret

set_real_mode ENDP

; Процедура, открывающая адресную линию А20. После открытия

; адресной линии программам будет доступна память свыше 1 Мбайт

enable_a20 PROC

mov al, A20_PORT

out STATUS_PORT, al

mov al, A20_ON

out KBD_PORT_A, al

ret

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату