加载中…
正文 字体大小:

跟踪了解80X86实模式和保护模式转换的技术细节(一)

(2006-09-08 16:44:36)
分类: 底层技术

一.编写实方式和保护方式切换演示程序

;编译要点 通过masm/link 生成exe文件,再用exe2bin转成.com文件

;演示实方式和保护方式切换
;----------------------------------------------------------------------------
INCLUDE         386SCD.INC

;----------------------------------------------------------------------------
CSEG            SEGMENT USE16                   ;16
位代码段
                ASSUME  CS:CSEG,DS:CSEG
org 08c00h      ;
为了便于通过bochs调试,写成COM,偏移为08c00h
                ;(
参见: 如何在windows下利用BOCHS调试80x86汇编程序
)
Start:
                jmp Begin
;----------------------------------------------------------------------------
GDT             LABEL   BYTE                    ;
全局描述符表

DUMMY           Desc    <>                      ;
空描述符
Code            Desc    <0ffffh,,,ATCE,,>       ;
代码段描述符
DataD           Desc    <8000,8000h,0bh,ATDW,,> ;
目标数据段描述符
Normal          Desc    <0ffffh,,,ATDW,,>       ;
规范段描述符
;----------------------------------------------------------------------------
GDTLen               $-GDT                   ;
全局描述符表长度
VGDTR           PDesc   <GDTLen-1,>             ;
伪描述符
;----------------------------------------------------------------------------
Code_Sel             Code-GDT                ;
代码段选择子
DataD_Sel            DataD-GDT               ;
目标数据段选择子
Normal_Sel           Normal-GDT              ;
规范段选择子
;----------------------------------------------------------------------------
DataLen              960                     ;
缓冲区字节长度
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
Begin:
                mov     ax,CSEG
                mov     ds,ax
                ;
准备要加载到GDTR的伪描述符
                mov     bx,16
                mul     bx
                add     ax,OFFSET GDT           ;
计算并设置基地址
                adc     dx,0                    ;
界限已在定义时设置好
                mov     WORD PTR VGDTR.Base,ax
                mov     WORD PTR VGDTR.Base+2,dx
                ;
设置代码段描述符
                mov     ax,cs
                mul     bx
                mov     WORD PTR Code.BaseL,ax  ;
代码段开始偏移为0
                mov     BYTE PTR Code.BaseM,dl  ;
代码段界限已在定义时设置好

                mov     BYTE PTR Code.BaseH,dh
                ;
加载GDTR
                lgdt    QWORD PTR VGDTR
                cli                             ;
关中断

                EnableA20                       ;
打开地址线A20
                ;
切换到保护方式

                mov     eax,cr0
                or      eax,1
                mov     cr0,eax
                ;
清指令预取队列,并真正进入保护方式
                JUMP16  Code_Sel,<OFFSET Virtual>
Virtual:        ;
现在开始在保护方式下运行
                mov     ax,DataD_Sel
                mov     es,ax                   ;
加载显示缓冲区描述符
                cld
                mov     di,320                  ;
设置指针初值
                mov     cx,DataLen              ;
设置数据长度
                mov     ax,7b1h
                repz    stosw
                mov     ax,Normal_Sel
                mov     es,ax
                ;
切换回实模式
                mov     eax,cr0
                and     al,11111110b
                mov     cr0,eax
                ;
清指令预取队列,进入实方式
                JUMP16  <SEG Real>,<OFFSET Real>
Real:           ;
现在又回到实方式
                DisableA20
                sti
                jmp $
;Start           ENDP
;----------------------------------------------------------------------------
CSEG            ENDS                            ;
代码段定义结束
;----------------------------------------------------------------------------
                END     Start

 

 

 

 

0

阅读 评论 收藏 转载 喜欢 打印举报
前一篇:雨后
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

    < 前一篇雨后
      

    新浪BLOG意见反馈留言板 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有