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...