首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 汇编语言 >

没法跳转到保护模式,求解答!

2013-01-09 
无法跳转到保护模式,求解答!!按照于渊书里的例子改了一下,结果发现跳转不到保护模式:------head.binorg01

无法跳转到保护模式,求解答!!
按照于渊书里的例子改了一下,结果发现跳转不到保护模式:

;------head.bin
org0100h

BaseAddressequ0

jmpSTART

%include "segment.inc"

BaseOfLoaderequ09000h; Head.bin被加载的地址
BasePhyAddrequBaseOfLoader*10h

;-----设置代码段、数据段描述符
LABEL_GDT:Descriptor0,0,0; 第一个GDT不使用,必须为0
LABEL_DESC_CR:Descriptor0,0fffffh,PST_C_R | F_G | F_D; 只读,4GB的32位代码段
LABEL_DESC_DRW:Descriptor0,0fffffh,PST_D_W | F_G | F_D; 可写,4GB的32位数据段
LABEL_DESC_VEDIO:Descriptor0B800h,0fffffh,PST_D_W | F_G | F_D; 可写,4GB的32位数据段

;-----设置lgdt操作数:6字节,低2字节段界限,高4字节段基地址
GdtLenequ$ - LABEL_GDT
GdtPtrdwGdtLen - 1
ddBasePhyAddr + LABEL_GDT ; 此处为物理地址

;-----设置段选择符(其实就是Descriptor在GDT表中的序号)
Selector_CequLABEL_DESC_CR-LABEL_GDT
Selector_DequLABEL_DESC_DRW-LABEL_GDT
Selector_VequLABEL_DESC_VEDIO-LABEL_GDT

START:

movax, 0B800h
movgs, ax
movah, 0Fh; 0000: 黑底    1111: 白字
moval, 'J'
movbx, ax
mov[gs:((80 * 0 + 20) * 2)], bx; 屏幕第 0 行, 第 39 列。


;-----Initialize hardware environment----

xor eax, eax
lgdt[GdtPtr]; 此时程序位于GDT表中(因为GdtPtr的基地址就为GDT的地址)

cli; 关中断
inal,0x92; 找到A20 I/O端口
oral,00000010b; 0x92快速A20 GATE格式如下:
; Bit 0 – 设成1来快速重设 (用于返回实模式)
; Bit 1 - 0: 关闭 A20; 1:开启 A20
; Bit 2 –制造商定义
; Bit 3 –电源口令(CMOS bytes 0x38-0x3f或0x36-0x3f). 0: 可访问 , 1:不可访问
; Bits 4-5 -制造商定义
; Bits 6-7 - 00: HDD 活动LED 灭;其他 "亮"
out0x92,al; 设置A20引脚

xoreax, eax
moveax, cr0; 设置CR0的PE位为1
oreax, 1
movcr0, eax


jmpdword Selector_C:(BaseOfLoader*10h + LABEL_PM_START); 表示跳转到代码段的LABEL_PM_START处

;jmpLABEL_PM_START:0


LABEL_PM_START:

movax,Selector_V
movgs, ax
movah, 0Ch; 0000: 黑底    1111: 白字
moval, 'M'
mov[gs:((80 * 7 + 40) * 2)], ax; 屏幕第 0 行, 第 39 列。

jmp$; 到此停住

用BOCHS调试的时候发现就是无法跳转到保护模式,不会显示字符‘M’,也不会将光标停留住。

已经困扰我很久了,跪求大神解答啊啊啊啊啊啊啊啊啊啊啊啊!

[解决办法]


         ;代码清单11-1
         ;文件名:c11_mbr.asm
         ;文件说明:硬盘主引导扇区代码 
           ;创建日期:2011-5-16 19:54

         ;设置堆栈段和栈指针 
           mov ax,cs      
         mov ss,ax
         mov sp,0x7c00
      
         ;计算GDT所在的逻辑段地址 
           mov ax,[cs:gdt_base+0x7c00]        ;低16位 
           mov dx,[cs:gdt_base+0x7c00+0x02]   ;高16位 


           mov bx,16        
         div bx            
         mov ds,ax                          ;令DS指向该段以进行操作
           mov bx,dx                          ;段内起始偏移地址 
      
           ;创建0#描述符,它是空描述符,这是处理器的要求
           mov dword [bx+0x00],0x00
         mov dword [bx+0x04],0x00  

         ;创建#1描述符,保护模式下的代码段描述符
           mov dword [bx+0x08],0x7c0001ff     
         mov dword [bx+0x0c],0x00409800     

         ;创建#2描述符,保护模式下的数据段描述符(文本模式下的显示缓冲区) 
           mov dword [bx+0x10],0x8000ffff     
         mov dword [bx+0x14],0x0040920b     

         ;创建#3描述符,保护模式下的堆栈段描述符
           mov dword [bx+0x18],0x00007a00
         mov dword [bx+0x1c],0x00409600

         ;初始化描述符表寄存器GDTR
         mov word [cs: gdt_size+0x7c00],31  ;描述符表的界限(总字节数减一)   
                                             
           lgdt [cs: gdt_size+0x7c00]
      
         in al,0x92                         ;南桥芯片内的端口 
           or al,0000_0010B
         out 0x92,al                        ;打开A20

         cli                                ;保护模式下中断机制尚未建立,应 
                                                     ;禁止中断 
           mov eax,cr0


         or eax,1
         mov cr0,eax                        ;设置PE位
      
           ;以下进入保护模式... ...
         jmp dword 0x0008:flush             ;16位的描述符选择子:32位偏移
                                                     ;清流水线并串行化处理器 
         [bits 32] 

    flush:
         mov cx,00000000000_10_000B         ;加载数据段选择子(0x10)
         mov ds,cx

         ;以下在屏幕上显示"Protect mode OK." 
         mov byte [0x00],'P'  
         mov byte [0x02],'r'
         mov byte [0x04],'o'
         mov byte [0x06],'t'
         mov byte [0x08],'e'
         mov byte [0x0a],'c'
         mov byte [0x0c],'t'
         mov byte [0x0e],' '
         mov byte [0x10],'m'
         mov byte [0x12],'o'
         mov byte [0x14],'d'
         mov byte [0x16],'e'
         mov byte [0x18],' '
         mov byte [0x1a],'O'
         mov byte [0x1c],'K'

         ;以下用简单的示例来帮助阐述32位保护模式下的堆栈操作 
           mov cx,00000000000_11_000B         ;加载堆栈段选择子
           mov ss,cx
         mov esp,0x7c00

         mov ebp,esp                        ;保存堆栈指针 
           push byte '.'                      ;压入立即数(字节)
         
           sub ebp,4
         cmp ebp,esp                        ;判断压入立即数时,ESP是否减4 


         jnz ghalt                          
         pop eax
         mov [0x1e],al                      ;显示句点 
      
  ghalt:     
         hlt                                ;已经禁止中断,将不会被唤醒 

;-------------------------------------------
     
         gdt_size         dw 0
         gdt_base         dd 0x00007e00     ;GDT的物理地址 
                             
           times 510-($-$$) db 0
                          db 0x55,0xaa

热点排行