switching between real mode and protected mode in x86 cpu's

Status
Not open for further replies.

eelinker

Full Member level 5
Joined
Feb 12, 2006
Messages
267
Helped
16
Reputation
32
Reaction score
8
Trophy points
1,298
Location
PERSIA
Activity points
2,775
i need help for programming guide for switching between real mode and protected mode in x86 cpu's.
 

Re: switching between real mode and protected mode in x86 cp

Hi eelinker!

Take a look at this code!



Code:
        ; 3. Program to switch to protected mode

        dosseg
        .MODEL SMALL
        .586p
        codeseg_offset equ 08h
        dataseg_offset equ 10h
        extraseg_offset equ 18h
        stackseg_offset equ 20h

;-----------------------------------------------------------------------------
; Segment Descriptor Structure
;-----------------------------------------------------------------------------
        segment_descriptor struc
        seg_length0_15  dw 0
        base_addr0_15   dw 0
        base_addr16_23  db 0
        flags           db 0
        access          db 0
        base_addr24_31  db 0
        segment_descriptor ends

;-----------------------------------------------------------------------------
; Macro used for 32-bit address calculation
;-----------------------------------------------------------------------------

        ADDR32 macro base,offsetadd
        mov eax,0
        mov ebx,eax
        mov ax,base
        shl eax,4           
        mov bx,offsetadd
        add ebx,eax
        endm
;-----------------------------------------------------------------------------
; Macro used for Displaying PE bit
;-----------------------------------------------------------------------------

        DISP macro
        mov ah,06H
        mov bl,6
        add al,30H
        mov dl,al
        int 21H
        endm

        dsetup macro dest
        movzx eax, ax
        shl eax, 4
        mov dest.base_addr0_15, ax
        shr eax, 8
        mov dest.base_addr16_23, ah
        endm
;-----------------------------------------------------------------------------
; Stack
;-----------------------------------------------------------------------------

stack16 segment para public use16
        assume cs:code16, ds:data16
        db 100 dup (?)

stack16_end label word
        db 100 dup (?)
        stack16 ends
;-----------------------------------------------------------------------------
; Data
;-----------------------------------------------------------------------------

data16 segment para public use16
        assume cs:code16, ds:data16

        MSG1    db "Switching to Protected Mode...Wait for sometime to switch back $"
        MSG2    db "PE BIT OF CRO after switching back is $"
        global_descriptor_table label fword

        gdt_start       dw gdt_size,0,0
        dummy_des       segment_descriptor <0,0,0,0,0,0>
        code16_des      segment_descriptor <0ffffh,0,0,9ah,0,0>
        data16_des      segment_descriptor <0ffffh,0,0,92h,0,0>
        extraseg_des    segment_descriptor <0ffffh,0,0,92h,0,0>
        stak16_des      segment_descriptor <00000h,0,0,96h,0,0>
        gdt_size        = $-(offset dummy_des)
        temp dw ?
        data16 ends

;-----------------------------------------------------------------------------
; Code starts
;-----------------------------------------------------------------------------

code16          segment para public use16
                        assume cs:code16, ds:data16
;-----------------------------------------------------------------------------
; Procedure used to implement delay
;-----------------------------------------------------------------------------

  delay PROC NEAR
        mov ecx,02ffffffH
   lop: dec ecx
        jnz lop
        ret
        delay endp

        start16:
        cli      ; turn off interrupts

 ; Set up real mode registers

        mov ax, data16
        mov ds, ax
        mov ax, stack16
        mov ss, ax
        mov sp, offset stack16_end
  ; Set up up the various pmode descriptiors

        mov ax, code16
        dsetup code16_des
        mov ax, data16
        dsetup data16_des
        mov ax, stack16
        dsetup stak16_des

 ; Set up the global descriptor table
        mov temp, offset dummy_des
        ADDR32     data16, temp
	
        mov        dword ptr ds:gdt_start[2],ebx

; Load Global Descriptor Table Register

        lgdt fword ptr ds:global_descriptor_table

 ; Display a message before switching to Protected mode

        mov dx,offset MSG1
        mov ah,09H
        int 21H

        ; Switch to Protected mode by setting PE bit of CR0

        mov eax,cr0
        or al,1
        mov cr0,eax
        db 0eah
        dw $+4, codeseg_offset

        ; Set up the pmode descriptors

        mov ax, dataseg_offset
        mov ds, ax
        mov ax, stackseg_offset
        mov ss, ax
        mov ax, extraseg_offset
        mov es, ax
        mov fs, ax
        mov gs, ax

        ; Give some delay in Protected mode
        call delay

        ; Switch back to real mode by resetting PE bit of CR0

        mov eax,cr0
        and al,not 1
        mov cr0,eax
        db 0eah
        dw $+4,code16
        mov ax, data16
        mov ds, ax
        mov es, ax
        mov ax, stack16
        mov ss,ax
        mov sp, offset stack16_end

        ; Turn interrupts back on and get back to DOS

        sti

        ; Print the PE bit of CR0

        mov dl,0AH
        mov ah,02H
        int 21H
        mov dl,0DH
        mov ah,02H
        int 21H
        mov dx,offset MSG2
        mov ah,09H
        int 21H
        mov eax,cr0
        and al,0001H

        ;Use the macro DISP to display PE bit of CR0

        disp 
        mov ax,4c00h
        int 21h
 code16 ends
   end start16
   end

Giri
 

    eelinker

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…