55 lines
1.4 KiB
NASM
55 lines
1.4 KiB
NASM
SECTION .text
|
|
USE16
|
|
|
|
; switch to unreal mode; ds and es can address up to 4GiB
|
|
unreal:
|
|
cli
|
|
|
|
lgdt [unreal_gdtr]
|
|
|
|
push es
|
|
push ds
|
|
|
|
mov eax, cr0 ; switch to pmode by
|
|
or al,1 ; set pmode bit
|
|
mov cr0, eax
|
|
|
|
jmp $+2
|
|
|
|
; http://wiki.osdev.org/Babystep7
|
|
; When this register given a "selector", a "segment descriptor cache register"
|
|
; is filled with the descriptor values, including the size (or limit). After
|
|
; the switch back to real mode, these values are not modified, regardless of
|
|
; what value is in the 16-bit segment register. So the 64k limit is no longer
|
|
; valid and 32-bit offsets can be used with the real-mode addressing rules
|
|
mov bx, unreal_gdt.data
|
|
mov es, bx
|
|
mov ds, bx
|
|
|
|
and al,0xFE ; back to realmode
|
|
mov cr0, eax ; by toggling bit again
|
|
|
|
pop ds
|
|
pop es
|
|
sti
|
|
ret
|
|
|
|
|
|
unreal_gdtr:
|
|
dw unreal_gdt.end + 1 ; size
|
|
dd unreal_gdt ; offset
|
|
|
|
unreal_gdt:
|
|
.null equ $ - unreal_gdt
|
|
dq 0
|
|
.data equ $ - unreal_gdt
|
|
istruc GDTEntry
|
|
at GDTEntry.limitl, dw 0xFFFF
|
|
at GDTEntry.basel, dw 0x0
|
|
at GDTEntry.basem, db 0x0
|
|
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable
|
|
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
|
|
at GDTEntry.baseh, db 0x0
|
|
iend
|
|
.end equ $ - unreal_gdt
|