V86:はい、進むべき道ですが、OSをセットアップする場合:
これを試してみてください(ロングモード用に設計されていますが、動作するはずです。これはまだテストしていませんが、まだ動作しない理由はわかりません。問題はnasmではありません。
LDH8s16ビットELF/aoutリファレンス。これは、GRUBからロードするための標準です。
32ビットCSがオフになっていることを知っているので、その場所を再確認する必要があります。それ以外の場合は問題ないようです。
これはコードを見つけるのが難しいです。
-;32ビットに変更しますか??
;this code is placed somewhere after 10000h
;-----we're in LONG MODE-----
mov dword [.stckptr], esp ;first of all save stack
sgdt [.gdtv32] ;save your gdt pointer
lgdt [.gdtv16] ;load a new one
sidt [.idt32] ;save your idt pointer
lidt [.idt16] ;load real mode idt
;far jump in long mode is not possible, do a trick
push DESC_REAL
push @f-10000h ;this is CS*10h, modify if needed!
retfd
.stckptr:
dd 0
align 16
.gdtv32:
dw 0
dd 0
align 16
.gdtv16:
dw .gdtend-.gdt-1
dd .gdt,0
align 16
.gdt:
dd 0,0 ;null descriptor
DESC_DATA=8 ;descriptor in YOUR GDT (modify)
DESC_LONG=$-.gdt
dd 00000000h,00209800h ;32 bit mode cs -MOD ME
DESC_REAL=$-.gdt
dd 0000FFFFh,00009801h ;16 bit real mode cs (modify base if needed!)
.gdtend:
align 16
.idt32:
dw 0
dd 0
align 16
.idt16:
dw 3FFh
dd 0
USE16
;-----we're in COMPATIBLITY MODE-----
;disable paging and protmode at once
@@: mov eax, cr0
and eax, 7FFFFFFEh
mov cr0, eax
;set up real mode segment registers and stack
mov esp, realmode_stack_top ;modify it to your needs!
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
;convert long mode rip to real mode cs:ip
;jmp CS:(pmode address)-CS*10h
jmp 1000h:@f-10000h ;modify if needed!
;-----we're in REAL MODE-----
@@: ;***********call some BIOS interrupt here**********
mov ax, 3
int 10h
;switch back to long mode
mov eax, cr0
or eax, 80000001h
mov cr0, eax ;enable protmode and paging
;jmp DESC_LONG:@f
db 66h
db 0EAh
dd @f
dw DESC_LONG
USE32
;-----we're in protected MODE-----
@@: lgdt [cs:.gdtv32] ;restore gdt
mov ax, DESC_DATA ;read YOUR DATA descriptor to selectors
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
lidt [.idt32] ;restore idt
mov rsp, qword [.stckptr] ;restore stack
;must be a non rip-relative jump
mov eax, @f
jmp eax
@@:
;AS WE WERE!