Real Mode Transition Code does not work
Posted: Wed Oct 23, 2013 5:40 pm
Hello, my code to transition to real mode is not working. I need to go back to real mode so my OS can shut the computer off using APM. The problem is that the instructions sti and ret throw-off the registers. cs is set to f000 on ret to the code that called it. es and ss are set to 0110 and 4749 on sti. Is there anything in my code that could mess up those registers?
Here is the code to switch to real mode:
Here is my GDT:
Here is the code to switch to real mode:
Code: Select all
BITS 32
realmode:
mov ebx, msgRealMode
call DisplayMessage
mov ebx, msgNWLN
call DisplayMessage
cli
jmp 0x18:switchrealmode
realidtr:
dw 0x3FF
dd 0
BITS 16
switchrealmode:
mov ax, 0x20
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
lidt [realidtr]
mov eax, cr0
and eax, ~1
mov cr0, eax
jmp 0:gorealmode
gorealmode:
mov ax, 0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov sp, sp
sti
ret
Code: Select all
NULL_DESC:
dd 0
dd 0
CODE_DESC:
dw 0xFFFF
dw 0
db 0
db 10011010b
db 11001111b
db 0
DATA_DESC:
dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0
;USER_CODE_DESC:
;dw 0xFFFF
;dw 0
;db 0
;db 11111010b
;db 11001111b
;db 0
;USER_DATA_DESC:
;dw 0xFFFF
;dw 0
;db 0
;db 11110010b
;db 11001111b
;db 0
SIXTEEN_CODE_DESC:
dw 0xFFFF
dw 0
db 0
db 10011010b
db 00001111b
db 0
SIXTEEN_DATA_DESC:
dw 0xFFFF
dw 0
db 0
db 10010010b
db 00001111b
db 0
gdtend:
gdtr:
GDTLimit dw gdtend-NULL_DESC-1
GDTBase dd NULL_DESC