怎样用jmp指令从保护模式转换为实模式?
时间:2011-10-23
来源:互联网
从实模式通过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
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
作者: liaozhicai 发布时间: 2011-10-23
如下代码,编译为启动代码,加载到7c00h处运行,显示为:s p,即在最初的实模式的显示s及切换到保护模式下显示p代码都能正常运行,但再切回到实模式后显示x代码段却没有执行,说明切换不成功,系统也没有崩溃,但没找到原因。请赐教,谢谢。
;功能:演示实方式和保护方式切换
;16位偏移的段间直接转移指令的宏定义
JUMP macro selector,offsetv
db 0eah ;操作码
dw offsetv ;16位偏移
dw selector ;段值或者选择子
endm
;存储段描述符结构类型的定义
DESCRIPTOR struc
LIMITL dw 0 ;段界限(0-15)
BASEL dw 0 ;段基地址(0-15)
BASEM db 0 ;段基地址(16-23)
ATTRIBUTES dw 0 ;段属性
BASEH db 0 ;段基地址(24-31)
DESCRIPTOR ends
;伪描述符结构类型的定义
PDESC struc
LIMIT dw 0 ;16界限
BASE dd 0 ;基地址
PDESC ends
;常量定义
ATDW = 92h ;存在的可读写数据段属性值
ATCE = 98h ;存在的只执行代码段属性值
;____________________________________________________
;
.386P
;_______________________________________________________
STARTSEG = 7c0h
STARTUPSEG_addr = STARTSEG
pseg_addr = STARTUPSEG_addr + (STARTUPSEG_END - STARTUPSEG_BEGIN + 0fh)/10h
cseg_addr = pseg_addr + (pseg_end - pseg_begin + 0fh)/10h
gdtseg_addr = cseg_addr + (cseg_end - cseg_begin + 0fh)/10h
;__________________________________________________________
;起始代码段
STARTUPSEG segment para use16 'STARTUP'
assume cs:STARTUPSEG
STARTUPSEG_BEGIN:
STARTUP:
JUMP <cseg_addr>,<offset start>
STARTUPSEG_END:
STARTUPSEG ends
;_______________________________________________________
;保护代码段
pseg segment use16
pseg_begin:
pbegin:
mov ax,DATAPRT_SEL
mov ds,ax
mov si,10h
mov [si],'p' ;能正常显示
mov [si+1],0ch
;切换回实方式
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
;清指令预取队列,进入实方式
JUMP <cseg_addr>,<offset REAL>
pseg_len = $ - pbegin
pseg_end:
pseg ends
;_______________________________________________________
;代码段
cseg segment use16 ;16位段
assume cs:cseg, ds:gdtseg
cseg_begin:
start:
mov ax,gdtseg_addr
mov ds,ax
;准备要加载到GDTR的伪描述符
mov bx,16
mul bx ;计算并设置GDT基地址
add ax,offset GDT ;界限已在定义时设置妥当
adc dx,0
mov word ptr VGDTR.BASE,ax
mov word ptr VGDTR.BASE+2,dx
;设置保护代码段描述符
mov ax,pseg_addr
mul bx
mov PCODE.BASEL,ax
mov PCODE.BASEM,dl
mov PCODE.BASEH,dh
;设置代码段描述符
mov ax,cseg_addr
mul bx
mov CODE.BASEL,ax ;代码段开始偏移为0
mov CODE.BASEM,dl ;代码段界限已在定义时设置妥当
mov CODE.BASEH,dh
;show r
mov ax,0b800h
mov es,ax
mov di,0
mov es:[di],'s' ;能正常显示
mov es:[di+1],0ch
;加载GDTR
LGDT fword ptr VGDTR
;
cli ;关中断
;切换到保护方式
mov eax,cr0
or eax,1
mov cr0,eax
;清指令预取队列,并真正进入保护方式
JUMP <PCODE_SEL>,<offset pbegin>
;
VIRTUAL:;现在开始在保护方式下
mov ax,DATAPRT_SEL
mov ds,ax
mov si,10h
mov [si],'p' ;程序运行,没有显示p字符!!!!!?
mov [si+1],0ch
;切换回实方式
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
;清指令预取队列,进入实方式
JUMP <cseg_addr>,<offset REAL>
;
REAL: ;现在又回到实方式
;sti ;开中断
;
mov ax,0b800h
mov es,ax
mov di,160
mov es:[di],'r'
mov es:[di+1],07h
;
jmp $
;
cseg_end:
cseg ends
;____________________________________________________________
;GDT段
gdtseg segment use16 ;16位段
gdtseg_begin:
GDT label byte ;全局描述表GDT
;________________________________
DUMMY DESCRIPTOR <> ;空描述符
;________________________________
PCODE DESCRIPTOR<pseg_len-1,,,ATCE,>
PCODE_SEL = PCODE - GDT
;_______________________________
CODE DESCRIPTOR <0ffffh,,,ATCE,>
CODE_SEL = CODE - GDT ;代码段描述符的选择子
;_________________________________
DATAPRT DESCRIPTOR <0ffffh,8000h,0bh,ATDW,0>
DATAPRT_SEL = DATAPRT - GDT ;屏幕显示段描述符的选择子
;__________________________________
GDTLEN = $ - GDT
;
VGDTR PDESC<GDTLEN-1,> ;伪描述符
gdtseg_end:
gdtseg ends
;-----------------------------------------------------------
end STARTUP
;功能:演示实方式和保护方式切换
;16位偏移的段间直接转移指令的宏定义
JUMP macro selector,offsetv
db 0eah ;操作码
dw offsetv ;16位偏移
dw selector ;段值或者选择子
endm
;存储段描述符结构类型的定义
DESCRIPTOR struc
LIMITL dw 0 ;段界限(0-15)
BASEL dw 0 ;段基地址(0-15)
BASEM db 0 ;段基地址(16-23)
ATTRIBUTES dw 0 ;段属性
BASEH db 0 ;段基地址(24-31)
DESCRIPTOR ends
;伪描述符结构类型的定义
PDESC struc
LIMIT dw 0 ;16界限
BASE dd 0 ;基地址
PDESC ends
;常量定义
ATDW = 92h ;存在的可读写数据段属性值
ATCE = 98h ;存在的只执行代码段属性值
;____________________________________________________
;
.386P
;_______________________________________________________
STARTSEG = 7c0h
STARTUPSEG_addr = STARTSEG
pseg_addr = STARTUPSEG_addr + (STARTUPSEG_END - STARTUPSEG_BEGIN + 0fh)/10h
cseg_addr = pseg_addr + (pseg_end - pseg_begin + 0fh)/10h
gdtseg_addr = cseg_addr + (cseg_end - cseg_begin + 0fh)/10h
;__________________________________________________________
;起始代码段
STARTUPSEG segment para use16 'STARTUP'
assume cs:STARTUPSEG
STARTUPSEG_BEGIN:
STARTUP:
JUMP <cseg_addr>,<offset start>
STARTUPSEG_END:
STARTUPSEG ends
;_______________________________________________________
;保护代码段
pseg segment use16
pseg_begin:
pbegin:
mov ax,DATAPRT_SEL
mov ds,ax
mov si,10h
mov [si],'p' ;能正常显示
mov [si+1],0ch
;切换回实方式
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
;清指令预取队列,进入实方式
JUMP <cseg_addr>,<offset REAL>
pseg_len = $ - pbegin
pseg_end:
pseg ends
;_______________________________________________________
;代码段
cseg segment use16 ;16位段
assume cs:cseg, ds:gdtseg
cseg_begin:
start:
mov ax,gdtseg_addr
mov ds,ax
;准备要加载到GDTR的伪描述符
mov bx,16
mul bx ;计算并设置GDT基地址
add ax,offset GDT ;界限已在定义时设置妥当
adc dx,0
mov word ptr VGDTR.BASE,ax
mov word ptr VGDTR.BASE+2,dx
;设置保护代码段描述符
mov ax,pseg_addr
mul bx
mov PCODE.BASEL,ax
mov PCODE.BASEM,dl
mov PCODE.BASEH,dh
;设置代码段描述符
mov ax,cseg_addr
mul bx
mov CODE.BASEL,ax ;代码段开始偏移为0
mov CODE.BASEM,dl ;代码段界限已在定义时设置妥当
mov CODE.BASEH,dh
;show r
mov ax,0b800h
mov es,ax
mov di,0
mov es:[di],'s' ;能正常显示
mov es:[di+1],0ch
;加载GDTR
LGDT fword ptr VGDTR
;
cli ;关中断
;切换到保护方式
mov eax,cr0
or eax,1
mov cr0,eax
;清指令预取队列,并真正进入保护方式
JUMP <PCODE_SEL>,<offset pbegin>
;
VIRTUAL:;现在开始在保护方式下
mov ax,DATAPRT_SEL
mov ds,ax
mov si,10h
mov [si],'p' ;程序运行,没有显示p字符!!!!!?
mov [si+1],0ch
;切换回实方式
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
;清指令预取队列,进入实方式
JUMP <cseg_addr>,<offset REAL>
;
REAL: ;现在又回到实方式
;sti ;开中断
;
mov ax,0b800h
mov es,ax
mov di,160
mov es:[di],'r'
mov es:[di+1],07h
;
jmp $
;
cseg_end:
cseg ends
;____________________________________________________________
;GDT段
gdtseg segment use16 ;16位段
gdtseg_begin:
GDT label byte ;全局描述表GDT
;________________________________
DUMMY DESCRIPTOR <> ;空描述符
;________________________________
PCODE DESCRIPTOR<pseg_len-1,,,ATCE,>
PCODE_SEL = PCODE - GDT
;_______________________________
CODE DESCRIPTOR <0ffffh,,,ATCE,>
CODE_SEL = CODE - GDT ;代码段描述符的选择子
;_________________________________
DATAPRT DESCRIPTOR <0ffffh,8000h,0bh,ATDW,0>
DATAPRT_SEL = DATAPRT - GDT ;屏幕显示段描述符的选择子
;__________________________________
GDTLEN = $ - GDT
;
VGDTR PDESC<GDTLEN-1,> ;伪描述符
gdtseg_end:
gdtseg ends
;-----------------------------------------------------------
end STARTUP
作者: liaozhicai 发布时间: 2011-10-23
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28