;16-разрядный код - завершающие действия по возврату в RM
; Необходимо обеспечить совпадение вирт. лин. и физ. адресов
finalproc: mov dx, FDATA
mov ds, dx
mov es, dx
mov fs, dx
mov gs, dx
mov ss, dx
mov sp, 8000h
lidt [FINAL_IDTR]
mov cr0, eax
jmp 0:@f
@@: mov cr3, ecx
mov ds, cx
mov es, cx
mov fs, cx
mov gs, cx
mov ss, cx
call reset_timer ; cx = 0
label RMIRQM word at $+1
mov dx, 0FFFFh
mov bx, 7008h
call reset_PIC
in al, 70h
and al, 7Fh
out 70h, al
sti
.
.
.
FINAL_GDT_BASE: dq 0
desc 0, 0FFFFh, DF_PRESENT or DF_DATA or DF_DUALACTION
desc 0, 0FFFFh, DF_PRESENT or DF_CODE or DF_DUALACTION
FINAL_GDT_SIZE = $-FINAL_GDT_BASE
; 32-разрядный код - начальные действия по возврату в RM
cli
in al, 70h
or al, 80h
out 70h, al
mov eax, cr0
and eax, 7FFFFFFEh
xor ecx, ecx
lgdt [FINAL_GDTR]
jmp FCODE:finalproc
.
.
.
FINAL_GDTR: dw FINAL_GDT_SIZE-1
dd FINAL_GDT_BASE
Выключение компьютера
Народ! Кто подскажет, как выключить компьютер из защищенного (или реального) режима в самопальной операционке?
Информацию можно найти по ссылке:
А как перейти в этот v86 из защищенного?
Здесь уже всплывала эта тема и, кажется, вполне сносный ответ по ней! Поищи!
Вот. Там есть неплохая ссылка (если конечно ресурс, на который она ссылается, еще не затерли)...
А как корректно выйти в реальный режим? Просто сбросом бита регистра cr0?
Вначале нужно подготовить переход, сделать так, чтобы адреса совпадали и там и там, и только потом выполнять переход.
ZhekkA, в том примере вроде бы используется интерфейс защищенного режима. Для корректного возвращения в реальный режим в общем случае нужно выполнить множество различных операций, чтобы все оборудование вернуть в исходное состояние. Само переключение выполнить не очень сложно...
Начало и конец поменялись местами (просто копировал в порядке размещения кода в исходниках :) ). Но, думаю, разберешься! finalproc находится в 16-разрядном сегменте с нулевой базой по смещению 500h. GDT с дескрипторами 16-разрядных сегментов, используемых при переходе я показал, FDATA и FCODE - это их селекторы. FINAL_IDTR у меня содержит сохраненное значение IDTR реального режима - в принципе его можно было не сохранять, а просто указать нулевую базу и корректный лимит IDT. RMIRQM - это сохраненное значение IMR контроллера прерываний. Вот вроде бы и все...