注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

编程学习

我的网上家园

 
 
 

日志

 
 

11章编程练习: 开启保护模式的大门  

2013-02-16 10:14:51|  分类: 《x86汇编语言: |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

开启保护模式的开关在CR0寄存器. CR0是32位的寄存器,它的第1位是保护模式允许位,是开启保护模式大门的门把手,如果把该位置1,则处理器进入保护模式.

mov eax,cr0

or eax,1

mov cr0,eax

但这样就可以了吗? 不是的! 在没有改变段寄存器CS DS ES SS 等寄存器的原有内容之前,处理器仍旧按照16位模式的方式运行,确切说是16位保护模式.

为什么说是16位保护模式呢? 当开启CR0以后,不涉及段寄存器的指令仍然按16位的方式执行,涉及到段寄存器的指令与实模式不同,而切换16位模式与32位模式的关键在于全局描述符表中的段定义.

需要注意的是实模式 保护模式 16位模式 32位模式的概念区别. 16位模式包括16位实模式跟16位保护模式. 16位模式的特点是指令是16位指令. 而实模式与保护模式的明显区别是内存访问机制的不同. 32位模式也有实模式.

 

改变CS寄存器的内容以后,代码运行方式转换为32位保护模式. 改变DS寄存器的内容以后,使用DS访问内存时,内存访问方式转换为32位保护模式. 需要注意的是,改变段寄存器的内容时,数值是全局描述符表的索引值,而不是 逻辑段地址. 明白这些之后,才能真正的明白保护模式是如何切换的.

以下是学习源代码,演示了保护模式的切换过程,重要的是,在开启CR0寄存器以后,没有改变CS原有内容之前,演示了处理器仍然是按以前的方式在运行.

xor ax,ax
mov ss,ax
mov sp,0x7c00
mov bx,ax
mov ax,0xb800
mov es,ax
mov cx,25*80
xsql:
 mov byte [es:bx],' '
 add bx,2
 loop xsql ;显示清屏
lea bx,[m1+0x7c00]
mov di,0
call show ;显示字符串,指示当前在实模式

;以下创建(定义)全局描述符表
mov ax,[cs:gdt_base+0x7c00]

mov dx,[cs:gdt_base+0x7c00+2]
mov bx,16
div bx
mov ds,ax
mov bx,dx
mov dword [bx],0
mov dword [bx+4],0
mov dword [bx+8],0x7c0001ff
mov dword [bx+0xc],0x00409a00 ;代码段 基地址0X7C00 界限0X1FF 可读
mov dword [bx+0x10],0x80000fa0
mov dword [bx+0x14],0x0040920b ;数据段 基地址0XB8000 界限0XFA0 向上扩展 可写
mov dword [bx+0x18],0x00007a00
mov dword [bx+0x1c],0x00409600 ;栈段 基地址 0X0 界限0X7A00 向下扩展 可写
mov word [cs:gdt_size+0x7c00],31 ;设定全局描述符表的界限
lgdt [cs:gdt_size+0x7c00] ;把全局描述符表GDT的地址与段界限传送到GDTR寄存器


in al,0x92
or al,2
out 0x92,al ;打开A20地址总线

cli ;关闭中断

mov eax,cr0
or eax,1
mov cr0,eax ;开启PE模式

;==============================================================================

; 以下这段用于证明开启CR0寄存器的PE模式以后,没有改变CS原有内容之前,处理器的运行模式

lea bx,[m2+0x7c00]
mov di,1*80*2
call show  ;测试开启PE模式以后,未改变段寄存器的原有内容之前,是否可以正常执行原有程序

;==============================================================================

jmp 0x8:m32mode  ;远跳转 刷新CS寄存器,改变段描述符高速缓存中的内容,使之按32保护模式运行


[bits 32]

m32mode:
mov ax,0x10
mov ds,ax ;刷新DS寄存器,从而改变DS 段描述符高速缓存中的内容,使之按32保护模式运行
mov ax,0x18
mov ss,ax
mov esp,0x7c00 ;刷新SS,同时设置ESP

;以下显示32 PE模式字串.

lea ebx,[m3]  ;EBX指向字符串位置 注意代码段的基地址是0X7C00
mov edi,2*80*2
show_32:
mov cl,[cs:ebx]
or cl,cl
jz m32_end
mov [edi],cl ;DS基地址0XB8000
inc edi
mov byte [edi],10
inc edi
inc ebx
jmp show_32
m32_end:
jmp $

 

 

[bits 16]

;显示子程序 入口参数: CS:BX指向字符串 ES:DI显示位置
show:
  push cx
  push bx
  push di
  xor ch,ch
 show_s:
    mov cl,[cs:bx]
  jcxz show_ret
  mov [es:di],cl
  inc di
  mov byte [es:di],10
  inc di
  inc bx
  jmp show_s
  show_ret:
    pop di
    pop bx
    pop cx
    ret
   
m1: db 'real mode.',0      
m2: db '16 pe mode.',0
m3: db '32 pe mode.',0
gdt_size: dw 0
gdt_base: dd 0x7e00


times 510-($-$$) db 0
db 0x55,0xaa

  评论这张
 
阅读(42)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017