Page 1 of 1

Real Mode Transition Code does not work

Posted: Wed Oct 23, 2013 5:40 pm
by gabemaiberger
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:

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
Here is my GDT:

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

Re: Real Mode Transition Code does not work

Posted: Thu Oct 24, 2013 9:48 am
by doxrobot
what is this
mov sp, sp
where are you branching too at the ret?

Re: Real Mode Transition Code does not work

Posted: Thu Oct 24, 2013 3:30 pm
by gabemaiberger
I am keeping the current value of sp and ret goes back to the kernel.

Re: Real Mode Transition Code does not work

Posted: Thu Oct 24, 2013 8:37 pm
by Octocontrabass
You can't return to your kernel. Your kernel is 32-bit code, but you've switched the CPU to 16-bit mode. You also need to set up a new stack for real mode.

Your registers are being trashed by STI because you've either overwritten something in the first 1KB of RAM, or you've reprogrammed the PIC.