我学习了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'
答案 0 :(得分:2)
设置PE(CR0的位0)后,处理器将以16位保护模式运行。跳到32位代码段是导致处理器开始以32位模式执行的步骤。因此,此代码中的远跳转指令以16位模式执行,并且默认情况下使用16位操作数。
按照迈克尔的建议,将fword属性应用于指令操作数,会导致汇编器在远跳转指令上放置操作数大小前缀,从而将该指令的操作数大小更改为32位。
另一种选择是将dd
标签上的far_jump
更改为dw
并继续使用16位远跳转指令,但前提是您知道32位入口点在内存的前64k之内。由于BIOS在7c00加载引导扇区,因此通常是这样。