操作系统-003- 进入保护模式

书中使用的一个宏定义来初始化描述符, 把3个参数按照规则填充到8个字节中,非常省事,那么后面有相同的表项,也可以按照这种方法来做

 

; 描述符

; usage: Descriptor Base, Limit, Attr

;        Base:  dd

;        Limit: dd (low 20 bits available)

;        Attr:  dw (lower 4 bits of higher byte are always 0)

%macro Descriptor 3

         dw   %2 & 0FFFFh                              ; 段界限1

         dw   %1 & 0FFFFh                              ; 段基址1

         db    (%1 >> 16) & 0FFh                    ; 段基址2

         dw   ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)     ; 属性1 + 段界限2 + 属性2

         db    (%1 >> 24) & 0FFh                    ; 段基址3

%endmacro ; 共 8 字节

本节代码无难点,还是得自己手写一遍,

进入保护模式的主要步骤

  1. 初始化GDT
  2. 将32位的代码段入口地址回填GDT
  3. 使用lgdt加载GDTR
  4. 打开A20
  5. 关中断
  6. 置cr0的PE位
  7. Jmp 保护模式

下面是记录自己出错的地方

%include "pm.inc"
org  100h     ;使用com,所以不用0x7c00
            jmp   LABEL_BEGIN

            ;1.	初始化GDT和GDTR
            [SECTION  .gdt]
            ;                          段基址         段界限         段属性
            LABEL_GDT:         Descriptor        0,             0,             0
            LABEL_DESC_CODE32: Descriptor        0, SegCode32Len - 1,  DA_C + DA_32
            LABEL_DESC_VIDEO:  Descriptor  0B8000h,         0ffffh,        DA_DRW

             Gdtlen    equ   $ - LABEL_GDT
             GdtPtr    dw    Gdtlen - 1
                       dd    0             ;加载的时候回填在内存中的位置
             ;选择子别名 ,第一次写直接LABEL_DESC_CODE32 ,debug大半天 
             SelectorCode32    equ    LABEL_DESC_CODE32  -  LABEL_GDT
             SelectorVideo     equ    LABEL_DESC_VIDEO   - LABEL_GDT 


[SECTION .S16]
[BITS 16]
LABEL_BEGIN:
            mov ax,cs
            mov ds,ax
            mov ss,ax
            mov es,ax
            mov sp,0100h

            ;2.	地址回填GDT/GDTR,描述符2,3  4,7字节
            xor eax,eax
            mov ax,cs
            shl eax,4
            add eax, LABEL_SEG_CODE32        ;逻辑地址换成线性地址
            mov word [LABEL_DESC_CODE32 + 2],ax
            shr eax,16
            mov byte [LABEL_DESC_CODE32 + 4],al
            mov byte [LABEL_DESC_CODE32 + 7],ah

            xor eax,eax
            mov ax,ds            ;数据段使用ds
            shl eax,4
            add eax, LABEL_GDT
            mov dword [GdtPtr + 2],eax

            ;3.	使用lgdt加载GDTR
            lgdt [GdtPtr]
            ;4.	 关中断
            cli
            ;5.	打开A20
            in al,92h
            or al,00000010b
            out 92h,al
            ;6.	置cr0的PE位
            mov eax,cr0
            or eax,1
            mov cr0,eax
            ;7.	Jmp 保护模式
            jmp dword SelectorCode32:0

[SECTION  .S32]
[BITS 32]
LABEL_SEG_CODE32:
            ;8.	对显存操作,输出一个字符
            mov ax, SelectorVideo
            mov es, ax
            mov edi,(80 * 11 + 79) * 2
            mov ah,0ch
            mov al,'D'
            mov [es:edi],ax

            jmp $

            SegCode32Len   equ  $-  LABEL_SEG_CODE32

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值