Переход в защищенный режим из DOS без использования DPMI

Я изучил сборку x86-16 и хочу научиться сборке x86-32. Я сделал простую 32-битную программу, но этот код не работает Когда программа совершает дальний прыжок, консоль отображает «Недопустимый дескриптор JMP 0». Я использую fasm и DOS. Пожалуйста, покажите мне, что я делаю плохо.

Вот мой код

format MZ

push cs
pop ds
mov eax,cs
shl eax,4
mov [AdresSegmentuProgramu_32],eax ;Calculating real mode segment
add eax,gdt_table
mov [gdtr+2],eax
use32
lgdt [gdtr]


mov eax,[AdresSegmentuProgramu_32]
add eax,pmode_entry
mov [AdresSegmentu_PMODE_entry],eax

mov eax,cr0
or eax,1    ;Switch to PMODE
mov cr0,eax

mov eax,[AdresSegmentu_PMODE_entry] ;Far jump to reset CS and jump to simple code
mov [far_jump],eax


jmp far [ds:far_jump]

far_jump:
dd 0
dw 08h ; Selector 0x08

gdtr: dw 128
dd 0


AdresSegmentuProgramu_32 dd 0
AdresSegmentu_PMODE_entry dd 0

use32

gdt_table:
dq 0
code_descriptor:
dw 0ffffh
dw 0
db 0
db 09ah
db 11001111b
db 0
data_descriptor:
dw 0ffffh
dw 0
db 0
db 092h
db 11001111b
db 0

dq 0
dq 0

pmode_entry:

mov esi,0b8000h
mov byte [esi],'a'

person micheal007    schedule 13.02.2019    source источник
comment
Помогут ли вам эти изменения: capp-sysware.com/misc/stackoverflow /54679254/pm.asm   -  person Michael Petch    schedule 14.02.2019
comment
Я внес изменения в код. Обнаружил, что могу получить желаемый эффект с модификатором fword, а не с db 66h.   -  person Michael Petch    schedule 14.02.2019
comment
Я предполагаю, что use32 делает то же самое, что .code32 в ассемблере GNU. В этом случае расположение первой use32 неверно: ЦП будет выполнять весь код в режиме use16 до инструкции jmp far. Он начнет выполнение кода в режиме use32 ПОСЛЕ инструкции jmp far. При использовании use32 перед инструкцией, которая выполняется в режиме use16, ассемблер сгенерирует неверный код.   -  person Martin Rosenau    schedule 14.02.2019
comment
В дополнение к другим предложениям здесь я предлагаю не размещать какой-либо код между переходом к cr0 и дальним прыжком. Это правильно, но может вызвать путаницу, и нет причин не ставить его перед изменением cr0.   -  person prl    schedule 14.02.2019
comment
@prl Среди прочего, я переместил код между установленным битом защищенного режима и JMP. Кроме того, я также отключил его прерывания, прежде чем перейти в защищенный режим. Присутствовал ошибочный use32 для 16-битной кодировки и модификатор FWORD. также примечательным был jmp $ в защищенном режиме, поэтому процессор не продолжает работать без кода. Наконец, селектор DS ни разу не был установлен в защищенном режиме перед доступом к памяти с неявным DS.   -  person Michael Petch    schedule 14.02.2019
comment
Спасибо. Теперь я могу переключиться в защищенный режим из DOS, не используя DPMI.   -  person micheal007    schedule 15.02.2019


Ответы (1)


После установки PE (бит 0 в CR0) процессор работает в 16-битном защищенном режиме. Дальний переход к 32-битному сегменту кода — это шаг, который заставляет процессор начать выполнение в 32-битном режиме. Таким образом, инструкция дальнего перехода в этом коде выполняется в 16-битном режиме и по умолчанию использует 16-битный операнд.

Применение атрибута fword к операнду инструкции, как советовал Майкл, заставляет ассемблер поместить префикс размера операнда в инструкцию дальнего перехода, изменяя размер операнда для этой инструкции на 32 бита.

Другой альтернативой является изменение dd в метке far_jump на dw и продолжение использования 16-битной инструкции дальнего перехода, но только если вы знаете, что 32-битная точка входа находится в пределах первых 64 КБ памяти. Поскольку BIOS загружает загрузочный сектор на 7c00, это обычно верно.

person prl    schedule 14.02.2019
comment
Поскольку это DOS (а не загрузчик), очень вероятно, что вычисленный физический адрес для FAR JMP будет выше отметки 64 КБ. Это было в моей версии DOSBox. После загрузки DOS загрузчик, вероятно, был почти стерт. В OP упоминается DOSBox, а формат DOS MZ соответствует началу исходного кода. Я поставил другие комментарии о том, что не так с кодом под вопросом. - person Michael Petch; 14.02.2019