Switch between protcted mode (32bits) to real mode (16bits) in asm, low level

0

I want to create a code to switch between protected mode and real mode but when I run my script, my emulator writes 00004513499i[CPU0 ] math_abort: MSDOS compatibility FPU exception 00004513500i[CPU0 ] math_abort: MSDOS compatibility FPU exception The GitHub project link is https://github.com/Keep-Konect/Konect-Help The code to switch to real mode is

global go16
;______________________________________________________________________________________________________
;Switch to 16-bit real Mode
;IN/OUT:  nothing

go16:
    [BITS 32]
    ;cli                 ;Clear interrupts    
    pop edx             ;save return location in edx
    jmp 0x20:PM16       ;Load CS with selector 0x20
;For go to 16-bit real mode, first we have to go to 16-bit protected mode
    [BITS 16]
PM16:
    mov ax, 0x28        ;0x28 is 16-bit protected mode selector.
    mov ss, ax  
    mov ds, ax
    mov es, ax
    mov gs, ax
    mov fs, ax
    mov sp, 0x7c00+0x200    ;Stack hase base at 0x7c00+0x200    

    
    mov eax, cr0
    and eax, 0xfffffffe ;Clear protected enable bit in cr0
    mov cr0, eax  
    jmp 0x50:realMode   ;Load CS and IP the error is here

realMode:
;Load segment registers with 16-bit Values.
    mov ax, 0x50
    mov ds, ax
    mov fs, ax
    mov gs, ax
    mov ax, 0
    mov ss, ax
    mov ax, 0
    mov es, ax
    mov sp, 0x7c00+0x200    
    lidt[.idtR]     ;Load real mode interrupt vector table
    sti

    push 0x50       ;New CS
    push dx         ;New IP (saved in edx)
    retf            ;Load CS, IP and Start real mode

;Real mode interrupt vector table
.idtR: 
    dw 0x03FF       ;Limit
    dd 0            ;Base

gdt:
gdt_null:
    dw 0, 0, 0, 0
gdt_cs:
    dw 0, 0, 0, 0
gdt_ds:
    dw 0, 0, 0, 0
gdtend:
gdtptr:
    dw 0x0000
    dd 0

The gdt is :

init_gdt_desc(0x0, 0x0, 0x0, 0x0, &kgdt[0]);
init_gdt_desc(0x0, 0xFFFFF, 0x9B, 0x0D, &kgdt[1]);      
init_gdt_desc(0x0, 0xFFFFF, 0x93, 0x0D, &kgdt[2]);    
init_gdt_desc(0x0, 0x0, 0x97, 0x0D, &kgdt[3]);          

//user segment modified
init_gdt_desc(0x0, 0xFFFF, 0x9E, 0x0, &kgdt[4]); /* ucode */
init_gdt_desc(0x0, 0xFFFF, 0x92, 0x0, &kgdt[5]); /* udata */
//normal gdt
//init_gdt_desc(0x0, 0xFFFFF, 0xFF, 0x0D, &kgdt[4]); /* ucode */
//init_gdt_desc(0x0, 0xFFFFF, 0xF3, 0x0D, &kgdt[5]); /* udata */
init_gdt_desc(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]);  

Thank you for your help, if you need somethings else in my code I can give it

c
assembly
operating-system
asked on Stack Overflow Jan 29, 2021 by Konect Team

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0