学习操作系统:进入保护模式,理解GDT(2):VGA

本章用另一种写法解释GDT,以及进入32位模式的方法

代码解析参照:https://blog.csdn.net/jinold/article/details/86561133

; 编译方法:nasm 32mode_VGA.asm -o 32mode_VGA.img
;--------------------------------------------------------------
        mov eax,cs      
        mov ss,eax
        mov sp,0x7c00
;-------------------- GDT ---------------------
        ;计算GDT所在的逻辑段地址
        mov eax,[cs:GdtPtr + 0x7c00 + 0x02]      ;GDT的32位线性基地址 
        xor edx,edx                        ;edx设置为0
        mov ebx,16
        div ebx                            ;eax和edx被分解成16位逻辑地址 

        mov ds,eax                         ;令DS指向该段以进行操作
        mov ebx,edx                        ;段内起始偏移地址 

        ;创建0#描述符,它是空描述符,这是处理器的要求
        mov dword [ebx + 0x00], 0x00000000
        mov dword [ebx + 0x04], 0x00000000  

        ;创建1#描述符,这是一个数据段,对应0~4GB的线性地址空间
        ;0x00cf920A0000ffff,拆分成两个dword。0x08为当前GDT选择子
        mov dword [ebx + 0x08], 0x0000ffff    ;基地址为0x000A0000,段界限为0xffff
        mov dword [ebx + 0x0c], 0x00cf920A    ;粒度为4KB,存储器段描述符 

        ;创建#2描述符,保护模式下初始代码段描述符
        mov dword [ebx + 0x10], 0x7c0001ff    ;基地址为0x00007c00,段界限为512字节 
        mov dword [ebx + 0x14], 0x00409800    ;粒度为1个字节,代码段描述符 

        ;创建#3描述符,以上代码段的别名描述符
        mov dword [ebx + 0x18], 0x7c0001ff    ;基地址为0x00007c00,段界限为512字节
        mov dword [ebx + 0x1c], 0x00409200    ;粒度为1个字节,数据段描述符

        ;创建#4描述符
        mov dword [ebx + 0x20], 0x7c00fffe    ;基地址为0x00007c00,段界限为0xfffe
        mov dword [ebx + 0x24], 0x00cf9600
        
        ;初始化描述符表寄存器GDTR
        mov word [cs: GdtPtr + 0x7c00], 39      ;描述符表的界限   

        lgdt [cs: GdtPtr + 0x7c00]
;--------------------以下设置显示模式(VGA) 开始 ---------------------
;INT 10H
;功能号:00H

;功能:设置显示模式
;入口参数:AH=00H
;   AL=显示模式
;显示模式列表:

;显示模式  显示模式属性
;  00H       40×25    16色 文本
;  01H       40×25    16色 文本
;  02H       80×25    16色 文本
;  04H       320×200   4色 
;  05H       320×200   4色
;  06H       640×200   2色
;  07H       80×25     2色 文本
;  08H       160×200  16色
;  09H       320×200  16色
;  0AH       640×200   4色
;  0BH       保留
;  0CH       保留
;  0DH       320×200  16色
;  0EH       640×200  16色
;  0FH       640×350   2色(单色)
;  10H       640×350   4色
;  11H       640×480   2色
;  12H       640×480  16色
;  13H       320×200 256色
        MOV		AH,0x00
        MOV		AL,0x13			; VGA 320x200x8bit Color
        INT		0x10
;--------------------以上设置显示模式(VGA)结束 ---------------------
;PIC的初始化,关闭PIC0(主PIC)和PIC1(从PIC), 必须是在cli指令之前完成
;PIC是中断控制寄存器,我们通常接触的PC机有主PIC和从PIC
        MOV		AL,0xff
        OUT		0x21,AL  ;pic0(主PIC)的端口
        NOP				 ;太快了,可能出问题,所以在这儿等会儿
        OUT		0xa1,AL  ;pic1(从PIC)的端口
;--------------------VGA 320x200x8bit Color  ---------------------

        cli                                ; 禁用可屏蔽中断

        mov eax,cr0      ; cr0是80386CPU中的控制寄存器
        or  eax,1        ; 第0位,即PE位,用来控制是否进入保护模式(是/否:1/0)
        mov cr0,eax      ; 设置PE位
     
        ;以下进入保护模式... ...
        jmp dword 0x0010:flush             ;16位的描述符选择子:32位偏移
                                            
[bits 32]                          
flush:                                      
        mov ax,1*8                     ;加载1#描述符的选择子,即数据段(0..4GB)选择子,
        mov ds,ax                      ;设置ds, es, fs, gs, ss的段地址为0x000a0000
        mov es,ax
        mov fs,ax
        mov gs,ax
        mov ss,ax		
        mov ebx,0x000a0000             ; 暂时不用段地址,直接指向VGA端口
printScreen:
        ;输出颜色到屏幕
        MOV	AL,0ah		;绿色
        MOV	ECX,ebx
        MOV	[ECX],AL
        inc ebx
        loop printScreen
        hlt

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

 [bits 32] 部分代码调整下

 不直接指定0x000a0000,而是在GDT(1#描述符)获取0x000a0000。

[bits 32]                          
flush:                                      
        mov ax, 1*8                     ;加载1#描述符的选择子,即数据段(0..4GB)选择子,
        mov ds, ax                      ;设置ds, es, fs, gs, ss的段地址为0x000a0000
        mov es, ax
        mov fs, ax
        mov gs, ax
        mov ss, ax	
        mov edi, 0
printScreen:
        ;输出颜色到屏幕
        mov AL, 0ah		;绿色
        mov [gs:edi], AL                 ;0x000a0000:0开始
        inc edi
        loop printScreen
        hlt
 
        GdtPtr    dw 0
                  dd 0x00007e00      ;GDT的物理地址

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值