Загрузка в 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 $ наблюдал за выполнением, после какого момента падала программа.


Ответы (0 шт):