对照代码重点理解一下三个要点:
1,从实模式到保护模式的整体过程;
2,实模式怎样安装GDT;
3,从实模式怎样过渡到安全模式;
4,安全模式怎样寻址;
代码如下:
;代码清单11-1;文件名:c11_mbr.asm;文件说明:硬盘主引导扇区代码 ;创建日期:2011-5-16 19:54;设置堆栈段和栈指针 mov ax,cs mov ss,axmov 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],0x00mov 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],0x00007a00mov dword [bx+0x1c],0x00409600;初始化描述符表寄存器GDTRmov word [cs: gdt_size+0x7c00],31 ;描述符表的界限(总字节数减一) lgdt [cs: gdt_size+0x7c00]in al,0x92 ;南桥芯片内的端口 or al,0000_0010Bout 0x92,al ;打开A20cli ;保护模式下中断机制尚未建立,应 ;禁止中断 mov eax,cr0or eax,1mov 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,cxmov esp,0x7c00mov ebp,esp ;保存堆栈指针 push byte '.' ;压入立即数(字节)sub ebp,4cmp ebp,esp ;判断压入立即数时,ESP是否减4 jnz ghalt pop eaxmov [0x1e],al ;显示句点 ghalt: hlt ;已经禁止中断,将不会被唤醒 ;-------------------------------------------------------------------------------gdt_size dw 0gdt_base dd 0x00007e00 ;GDT的物理地址 times 510-($-$$) db 0db 0x55,0xaa
实验结果: