first, the code:
Code: Select all
jmp EnablePMode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GDT ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GDT_START:
gdt_NULL:
dd 0
dd 0
gdt_CODE:
dw 0xFFFF
dw 0
db 0
db 10011010b ; 0x9A
db 11001111b ; 0xCF
db 0
gdt_DATA:
dw 0xFFFF
dw 0
db 0
db 10010010b ; 0x92
db 11001111b ; 0xCF
db 0
gdt_VRAM:
dw 0x0F9F
dw 0x8000
db 0x0B
db 10010010b ; 0x92
db 00000000b ; 0x00
db 0x00
GDT_END:
GDT_DESC:
limit dw GDT_END - GDT_START - 1
base dd GDT_START+0x10000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Selectoren ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
nullsel equ 000000000000000b
codesel equ 000000000001000b
datasel equ 000000000010000b
vramsel equ 000000000011000b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PMode ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EnablePMode:
cli
lgdt [GDT_DESC] ; GDT laden
mov eax, cr0 ; Das CR0 Register in eax laden
or eax, 1 ; Das 0. Bit (PE Bit) auf 1 setzen
mov cr0, eax ; Den neuen Wert in CR0 laden
jmp long 0x08:PM2+0x10000
[Bits 32]
PM2:
; Selector
mov ax, datasel
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x1FFFFF
sti
call check ;;;;This is the Function
chk01:
jmp chk01
jmp ende
;;;;TEST
check:
push eax
pop eax
ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CRASH
I switch to PM. This works fine.
Than I want to call a function (check), works fine, too.
I push and pop something, works!
but at the ret, the PC reboots...
why?? I can jump, and I can use the Stack. Why does ret crash?
ps.: this foult happans on a real PC (I tested it with 2 PCs). With bochs, ret works.