不使用 DPMI 从 DOS 切换到保护模式

Switching to protected mode from DOS not using DPMI

我学习了 x86-16 汇编,我想学习 x86-32 汇编。 我制作了一个简单的 32 位程序,但这段代码不起作用 当程序跳远时控制台显示 'JMP illegal descriptor 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'

设置 PE(CR0 的位 0)后,处理器 运行 处于 16 位保护模式。远跳转到 32 位代码段是导致处理器开始以 32 位模式执行的步骤。因此这段代码中的远跳转指令是在16位模式下执行的,默认使用16位操作数。

按照 Michael 的建议,将 fword 属性应用于指令操作数会导致汇编程序在远跳转指令上放置一个操作数大小前缀,从而将该指令的操作数大小更改为 32 位。

另一种方法是将far_jump标签处的dd改为dw并继续使用16位远跳转指令,但前提是你知道32 -bit 入口点在内存的前 64k 内。由于 BIOS 在 7c00 加载引导扇区,这通常是正确的。