从实模式通过jmp转为保护模式之后,再从保护模式通过jmp转为实模式,如果实模式与保护模式是两个独立的段,结果失败了,是一个段的话,能成功,为什么?
jump <selector>,<offsetv>:db 0eah;dw offsetv;dw selector
rseg segment use16
start:
;初始化gdt及vgdt,加载gdtr
lgdt fword vgdt
mov eax,cr0
or eax,1
mov cr0,eax
jump <pcode_sel>,<offset pbegin>---转入保护模式
real:
;show shome thing
jmp $
rseg ends
pseg segment use16
pbegin:
;show something
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
jump <seg rseg>,<offset real>-----转回实模式失败?为什么?
pseg ends
gdtseg segment use16
gdt label byte
dummy descriptor<>
PCODE descriptor<>
pcode_sel = PCODE - gdt
gdtlen = $ - gdt
vgdtr pdesc<gdtlen-1,>
gdtseg ends
end start
如果将实模式代码段及保护模式代码段合并为一个段,则能成功:gdt定义:
CODE descriptor<>;指向rseg
code_sel = CODE - gdt
rseg segment use16
start:
;初始化gdt及vgdt,加载gdtr
lgdt fword vgdt
mov eax,cr0
or eax,1
mov cr0,eax
jump <code_sel>,<offset virtual>---转入保护模式
virtual:
;show something
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
jump <seg rseg>,<offset real>
real:
;show shome thing
jmp $
rseg ends
------解决方案--------------------------------------------------------
当程序跳转到保护模式时它的cs已发生了变化,不再是以前的cs,所以再次跳转到实模式时,用seg…… offset…… 给出的地址就不对了,另外当系统产生中断时,也不一定会崩溃,比如0DH中断
------解决方案--------------------------------------------------------
mark下!11
------解决方案--------------------------------------------------------
用bochs调试下看看就知道了
------解决方案--------------------------------------------------------
写这种代码,BOCHS 很有用,你要从保护模式进入实模式,首先要从32位段跳到一个16位段,然后从16位段跳到实模式。否则直接进入实模式会导致CPU无法正确识别指令。