Загрузка в Protected mode и возврат в Real mode
Пишу программу на yasm для загрузки из RM в PM и обратно для голого железа, образ создаю в ultraISO (.bin выставляю загрузочным файлом). Запускаю на Hyper-V.
Компилирую следующей командой:
yasm-1.3.0-win64.exe -m x32 boot.asm -o boot.bin
Проблема в следующем:
Когда выполнение доходит до метки ; ERROR below, 3 команды после которой - это far jmp, то ВМ падает
boot.asm :
org 7C00h
jmp main
; NonExec description
struc SegDes
lim: resw 1
base_1: resw 1
base_m: resb 1
attr_1: resb 1
attr_2: resb 1
base_h: resb 1
endstruc
; NonExec description
data segment use16
; Instances of SegDes
gdt_null: istruc SegDes
at lim, dw 0
at base_1, dw 0
at base_m, db 0
at attr_1, db 0
at attr_2, db 0
at base_h, db 0
iend
gdt_data: istruc SegDes
at lim, dw data_size
at base_1, dw 0
at base_m, db 0
at attr_1, db 92h
at attr_2, db 0
at base_h, db 0
iend
gdt_code: istruc SegDes
at lim, dw code_size
at base_1, dw 0
at base_m, db 0
at attr_1, db 98h
at attr_2, db 0
at base_h, db 0
iend
gdt_stack: istruc SegDes
at lim, dw 255
at base_1, dw 0
at base_m, db 0
at attr_1, db 92h
at attr_2, db 0
at base_h, db 0
iend
gdt_screen: istruc SegDes
at lim, dw 3999
at base_1, dw 8000h
at base_m, db 0Bh
at attr_1, db 92h
at attr_2, db 0
at base_h, db 0
iend
; Instances of SegDes
gdt_size equ $-gdt_null
pdescr: times 6 db 0
sym db 1
attr db 1Eh
msg db 27, '[31;42 RealMode! ', 27, '[0m$'
data_size equ $-gdt_null
text segment use16
;assume CS:text, DS:data
main:
xor EAX, EAX
mov AX, data
mov DS, AX
shl EAX, 4
mov EBP, EAX
mov [gdt_data+base_1], AX
shr EAX, 16
mov [gdt_data+base_m], AL
xor EAX, EAX
mov AX, CS
shl EAX, 4
mov [gdt_code+base_1], AX
shr EAX, 16
mov [gdt_code+base_m], AL
xor EAX, EAX
mov AX, SS
shl EAX, 4
mov [gdt_stack+base_1], AX
shr EAX, 16
mov [gdt_stack+base_m], AL
mov dword [pdescr+2], EBP
mov word [pdescr], gdt_size-1
lgdt [pdescr]
mov AX, 40h
mov ES, AX
mov word [ES:67h], return
mov [ES:69h], CS
mov AL, 0Fh
out 70h, AL
mov AL, 0Ah
out 71h, AL
cli
mov EAX, CR0
or EAX, 1
mov CR0, EAX
; ERROR below
db 0EAh
dw continue
dw 16
continue:
mov AX, 8
mov DS, AX
mov AX, 24
mov SS, AX
mov AX, 32
mov ES, AX
mov DI, 1920
mov CX, 80
mov AX, word [sym]
scrn:
stosw
inc AL
loop scrn
jmp $
mov EAX, CR0
and EAX, 0FFFEh
mov CR0, EAX
jmp $
return:
mov AX, data
mov DS, AX
mov AX, stack
mov SS, AX
mov SP, 256
;sti
jmp $
code_size equ $-main
stack segment use16
times 256 db '^'
times 510 - ($ - $$) db 0 ;Заполнение оставшихся байт нулями до 510-го байта
db 0x55, 0xAA ;Загрузочная сигнатура
С jmp $ наблюдал за выполнением, после какого момента падала программа.