Page 1 of 1
Going back into real mode...
Posted: Mon Jun 07, 2004 11:00 pm
by EclipseOS
Hey, I have an assembly code that I need to run on my os, but I can;t run it in protected mode, does anyone have some code on going back into real mode? Thanx alot for your help. I need it to use int 15 to poweroff the computer.
RE:Going back into real mode...
Posted: Thu Jun 10, 2004 11:00 pm
by GT
I used to switch back to real mode for making BIOS calls, then back to protected mode when done. I no longer do this as I now have a working Virtual-8086 mode, but here's the snatch of code I used to use to drop down to real mode from protected mode. It follows the procedure described in the IA-32 Intel Architecture Software Developer's Manual, Volume 3: System Programming Guide. The comments refer to the sections in that manual. 0x0008 is a 16-bit code segment and 0x0010 a 16-bit data segment in my GDT. The code enters from 32-bit protected mode, kicks down into 16-bit protected mode, and finally switches into real mode. The 16-bit pmode steps are necessary to set the hidden upper bits of the segment selectors properly -- otherwise you end up in "unreal mode" (which can be fun but probably isn't what you want).
; See IA-32 Dev vol 3 sec 8.9.2 & 1 for explanation of steps mentioned below
cli ; 8.9.2. Step 1.
mov eax,cr0 ; 8.9.2. Step 2.
and eax,0x7FFFFFFF
mov cr0,eax
xor eax,eax
mov cr3,eax
jmp 0x0008:.prot16 ; 8.9.2. Step 3.
[bits 16]
.prot16 nop
mov ax,0x0010 ; 8.9.2. Step 4.
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov ax,0x03FF ; 8.9.2. Step 5.
mov [newidt],ax
xor ax,ax
mov [newidt+2],ax
mov [newidt+4],ax
lidt [newidt]
mov eax,cr0 ; 8.9.2. Step 6.
and eax,0xFFFFFFFE
mov cr0,eax
jmp dword 0x0000:.real16 ; 8.9.2. Step 7.
.real16 nop
xor ax,ax ; 8.9.2. Step 8.
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
sti ; 8.9.2. Step 9.
RE:Going back into real mode...
Posted: Mon Jun 28, 2004 11:00 pm
by EclipseOS
Hey thanx for your reply! I forgot about this post until I was searching for help on this and it came up on google. The one problem that I am having with your code is:
What is newidt? Nasm comes up with an error. Thanx alot again!
Brandon Holland
RE:Going back into real mode...
Posted: Mon Jun 28, 2004 11:00 pm
by GT
Ah, forgot about that, it's defined elsewhere, it's actually just 6 bytes of memory, could be anywhere... here's where it's defined:
newidt equ 0x632
You could just as easily use:
newidt dw 0
dd 0
In my case I was using specific defined addresses in lower memory to exchange data between real mode assembly and pmode C, so I just threw newidt in with all the other defines. As the code sets the values before using it, it doesn't actually need to be initialized to zeroes...