码迷,mamicode.com
首页 > 其他好文 > 详细

第十四天、试验保护模式

时间:2015-11-15 13:35:44      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:

    总算把进入保护模式的代码读懂了,照抄贴出来,讲是讲不明白了!!

; TestPM.nas
; 初识保护模式
; 四彩
; 2015-11-15


; ========================================================================================
; ----------------------------------------------------------------------------------------
; 描述符说明(8 字节 64 位)
;
;  ------ ┏━━┳━━┓内存高地址
;         ┃ 7  ┃ 段 ┃
;         ┣━━┫ 基 ┃
;         ┆    ┆ 址 ┆
;  字节   ┆    ┆ 高 ┆
;   7     ┣━━┫ 8  ┃
;         ┃ 0  ┃ 位 ┃
;  ------ ┣━━╋━━┫
;         ┃ 7  ┃ G  ┃
;         ┣━━╉━━┨
;         ┃ 6  ┃D/B ┃
;         ┣━━╉━━┨
;         ┃ 5  ┃ 未 ┃
;         ┣━━┫ 定 ┃
;         ┃ 4  ┃ 义 ┃
;  字节   ┣━━╉━━┨
;   6     ┃ 3  ┃    ┃
;         ┣━━┫ 段 ┃
;         ┃ 2  ┃ 界 ┃
;         ┣━━┫ 限 ┃
;         ┃ 1  ┃ 高 ┃
;         ┣━━┫ 4  ┃
;         ┃ 0  ┃ 位 ┃
;  ------ ┣━━╋━━┫
;         ┃ 7  ┃ P  ┃
;         ┣━━╉━━┨
;         ┃ 6  ┃ D  ┃
;         ┣━━┫ P  ┃
;         ┃ 5  ┃ L  ┃
;         ┣━━╉━━┨
;         ┃ 4  ┃ S  ┃
;  字节   ┣━━╉━━┨
;   5     ┃ 3  ┃    ┃
;         ┣━━┫ T  ┃
;         ┃ 2  ┃ Y  ┃
;         ┣━━┫ P  ┃
;         ┃ 1  ┃ E  ┃
;         ┣━━┫    ┃
;         ┃ 0  ┃    ┃
;  ------ ┣━━╋━━┫
;         ┃ 23 ┃    ┃
;         ┣━━┫    ┃
;         ┃ 22 ┃ 段 ┃
;         ┣━━┫ 基 ┃
;         ┆    ┆ 址 ┆
;  字节   ┆    ┆ 低 ┆
; 2,3,4 ┣━━┫ 24 ┃
;         ┃ 1  ┃ 位 ┃
;         ┣━━┫    ┃
;         ┃ 0  ┃    ┃
;  ------ ┣━━╋━━┫
;         ┃ 15 ┃    ┃
;         ┣━━┫    ┃
;         ┃ 14 ┃ 段 ┃
;         ┣━━┫ 界 ┃
;         ┆    ┆ 限 ┆
;  字节   ┆    ┆ 低 ┆
;  0,1   ┣━━┫ 16 ┃
;         ┃ 1  ┃ 位 ┃
;         ┣━━┫    ┃
;         ┃ 0  ┃    ┃
;  ------ ┗━━┻━━┛内存低地址
;
; 描述符定义宏:(看不明白的话,把 16 进制换成 2 进制就很清楚了)
; 调用格式:Descriptor Base, Limit, Attribute
;         Base      : dd               ; 基址,32 位
;         Limit     : dd               ; 界限,32 位,低 20 位有效
;         Attribute : dw               ; 属性,16 位,高 4 位和低 8 位有效,中间 4 位无效。
%macro Descriptor 3
    dw %2 & 0xFFFF                          ; 界限低 16 位
    dw %1 & 0xFFFF                          ; 基址低 16 位
    db (%1 >> 16) & 0xFF                    ; 基址中间 8 位(高字节的低字)
    dw ((%2 >> 8) & 0xF00) | (%3 & 0xF0FF)  ; 属性低 8 位 + 界限高 4 位 + 属性高 4 位 =
                                       ; %2 的高字的低字节的低 4 位替换 %3 高字中的低 4 位
    db (%1 >> 24) & 0xFF                    ; 基址高 8 位
%endmacro                                   ; 共占用 8 个字节(64 位)
;
; ----------------------------------------------------------------------------------------
; 描述符属性:
; 描述符属性是一个字型数值,但是只有高 4 位和低 8 位有效,中间 4 位无效。
;  ┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓
;  ┃15┃14┃13┃12┃11┃10┃09┃08┃07┃06┃05┃04┃03┃02┃01┃0 ┃
;  ┣━┻━┻━┻━╋━┻━┻━┻━╋━╋━┻━╋━╋━┻━┻━┻━┫
;  ┃G ┃DB┃R ┃A ┃    无效位    ┃P ┃  DPL ┃S ┃     TYPE     ┃
;  ┗━┻━┻━┻━┻━━━━━━━┻━┻━━━┻━┻━━━━━━━┛
;  11、G:Granularity,界限粒度位
;    G = 0 界限粒度为 1 字节;
;    G = 1 界限粒度为 4K 字节。
;    注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位。
;
;  10、DB:Default operation size / default stack pointer size and/or upper bound
;      默认操作大小/默认栈指针大小和/或上界限位,根据描述的段不同,功能不同。
;      对于 32 位代码和数据段,应该总是设置为 1;对于 16 位代码和数据段,应该总是设置为 0。
;    ⑴ 可执行代码段(D):指明指令引用有效地址和操作数的默认长度。
;      ① D = 1 默认为 32 位代码段,指令使用 32 位地址及 32 或 8 位操作数;
;      ② D = 0 默认为 16 位代码段,指令使用 16 位地址及 16 或 8 位操作数。
;      可以使用指令前缀 0x66 来选择非默认值的操作数大小、0x67 来选择非默认值的地址大小。
;    ⑵由 SS 寄存器指向的数据段,通常为堆栈段(B):指明堆栈操作指令默认栈指针大小。
;      ① D = 1 使用 32 位堆栈指针寄存器 ESP;
;      ② D = 0 使用 16 位堆栈指针寄存器 SP。
;    ⑶ 向下扩展数据段(B):指明段的上界限。
;      ① D = 1 段的上界限为 4G;
;      ② D = 0 段的上界限为 64K。
;
;  09、R:Reserved,保留位
;    未定义,应该总是设置为 0。
;
;  08、A:Available,可用位
;    未定义,可供系统软件使用。
;
;  07、P:Present,段存在位
;    P = 1 该段在内存中,即该段存在,或者说描述符对地址转换是有效的;
;    P = 0 该段不在内存中,即该段不存在,或者说描述符对地址转换无效。
;          把指向这个段描述符的选择符加载进段寄存器将导致产生一个段不存在异常。
;          内存管理软件可以使用这个标志来控制在某一给定时间实际需要把那个段加载进内存中。
;          这个功能为虚拟存储提供了除分页机制以外的控制。
;          操作系统可以使用该描述符来保存其他数据,如不存在段实际在什么地方。
;
; 06 05、DPL:Descriptor Privilege level,特权级位
;    规定了所描述段的特权级,用于特权检查,以决定对该段能否访问。
;    特权级范围从 0 到 3,0 级特权级最高,3 级最低。
;
;  04、S:Descriptor type flag,描述符类型位
;    S = 1 存储段
;    S = 0 系统段和门
;
; 03 02 01 00、TYPE:说明存储段描述符所描述的存储段的具体属性。
;      值        说明
; ------------------------------------------
;  系  0    未定义
;      1    可用 286TSS
;      2    局部描述符表
;      3    忙的 286TSS
;      4    286 调用门
;      5    任务门
;      6    286 中断门
;  统  7    286 陷阱门
;      8    未定义
;      9    可用 386TSS
;      A    未定义
;      B    忙的 386TSS
;      C    386 调用门
;      D    未定义
;      E    386 中断门
;  段  F    386 陷阱门
; ------------------------------------------
;  数  0    只读
;      1    只读、已访问
;      2    读/写
;  据  3    读/写、已访问
;      4    只读、向下扩展
;      5    只读、向下扩展、已访问
;      6    读/写、向下扩展
;  段  7    读/写、向下扩展、已访问
; ------------------------------------------
;  代  8    只执行
;      9    只执行、已访问
;      A    执行/读
;  码  B    执行/读、已访问
;      C    只执行、一致码段
;      D    只执行、一致码段、已访问
;      E    执行/读、一致码段
;  段  F    执行/读、一致码段、已访问
;
; ----------------------------------------------------------------------------------------
; 描述符属性常量定义:
; G 位,默认 1 字节粒度
DA_4k           equ 0x8000  ; 4K 字节粒度,0b 1 000 0000 0000 0000
;
; DB 位,默认 16 位
DA_32           equ 0x4000  ; 32 位,0b 1 00 0000 0000 0000
;
; DPL 位,默认特权级 0
DA_DPL_1        equ 0x20    ; DPL = 1,0b 01 0 0000
DA_DPL_2        equ 0x40    ; DPL = 2,0b 10 0 0000
DA_DPL_3        equ 0x60    ; DPL = 3,0b 11 0 0000
;
; P + S + TYPE 位
; 都存在,代码段都可执行
; P 存在:0x80,0b 1 000 0000,
; S 存储段:0x10,0b 1 0000
; 系统段
DA_SS_LDT       equ 0x82    ; 局部描述符表
DA_SS_TG        equ 0x85    ; 任务门
DA_SS_386TSS    equ 0x89    ; 可用 386 TSS(任务状态)段
DA_SS_386CG     equ 0x8C    ; 386 调用门
DA_SS_386IG     equ 0x8E    ; 386 中断门
DA_SS_386TG     equ 0x8F    ; 386 陷阱门
; 数据段
DA_DS_R         equ 0x90    ; 只读数据段
DA_DS_RW        equ 0x92    ; 可读写数据段
DA_DS_RWA       equ 0x93    ; 可读写、已访问数据段
; 代码段
DA_CS           equ 0x98    ; 代码段
DA_CS_R         equ 0x9A    ; 可读代码段
DA_CS_C         equ 0x9C    ; 一致代码段
DA_CS_RC        equ 0x9E    ; 可读、一致代码段
;
; ****************************************************************************************


; ========================================================================================
; 选择子:
; ----------------------------------------------------------------------------------------
;  ┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓
;  ┃15┃14┃13┃12┃11┃10┃09┃08┃07┃06┃05┃04┃03┃02┃01┃0 ┃
;  ┣━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━┻━╋━╋━┻━┫
;  ┃                   描述符索引                     ┃TI┃  RPL ┃
;  ┗━━━━━━━━━━━━━━━━━━━━━━━━━┻━┻━━━┛
;  TI:Table Indicator,引用描述符表位
;    TI = 0 从全局描述符表(GDT)中读取描述符;
;    TI = 1 从局部描述符表(LDT)中读取描述符。
;  RPL:Requested Privilege Level,请求特权级位
;    用于特权检查。
;
; ----------------------------------------------------------------------------------------
; 选择子属性常量定义:
; TI 位,默认为全局描述符表
SA_LDT          equ 4       ; 局部描述符表
;
; RPL 位,默认请求特权级 0
SA_RPL_1        equ 1
SA_RPL_2        equ 2
SA_RPL_3        equ 3
;
; ****************************************************************************************


; ========================================================================================
; ----------------------------------------------------------------------------------------
    org 0x7C00
    jmp Label_RM_main

; ****************************************************************************************


; ========================================================================================
; ----------------------------------------------------------------------------------------
; GDT                          段基址   段界限    属性
Label_Desc_Empty  : Descriptor 0,       0,        0                 ; 空描述符
Label_Desc_PM     : Descriptor 0,       0xFFFF,   DA_32 + DA_CS     ; 保护模式代码段描述符
Label_Desc_Video  : Descriptor 0xB8000, 0xFFFF,   DA_DS_RW          ; 显存段描述符

; ----------------------------------------------------------------------------------------
; GDTPtr
GDTLen  equ $ - Label_Desc_Empty
GDTPtr  dw  GDTLen - 1                      ; 界限
        dd  0                               ; 基址

; ----------------------------------------------------------------------------------------
; 选择子
SelectorPM      equ Label_Desc_PM    - Label_Desc_Empty
SelectorVideo   equ Label_Desc_Video - Label_Desc_Empty

; ****************************************************************************************


[BITS 16]
; ========================================================================================
; 实模式下开启保护模式
; ----------------------------------------------------------------------------------------
; 程序入口,实模式代码段
Label_RM_main:
    ; 填上保护模式代码段描述符的基址(界限、属性在定义时已初始化)
    xor eax, eax
    mov ax, cs
    shl eax, 4
    add eax, Label_PM_main                  ; 保护模式程序入口的绝对内存地址,即为其基址
    mov word[Label_Desc_PM + 2], ax         ; 拆分成 3 部分存入相应位置
    shr eax, 16
    mov byte[Label_Desc_PM + 4], al
    mov byte[Label_Desc_PM + 7], ah

    ; 填上 GDTPtr 的基址(界限在定义时已初始化)
    xor eax, eax
    mov ax, cs
    shl eax, 4
    add eax, Label_Desc_Empty
    mov dword[GDTPtr + 2], eax

    ; 加载 GDT
    lgdt [GDTPtr]

    ; 屏蔽中断
    cli

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

    ; 切换到保护模式
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    ; 修改 CS : EIP
    jmp dword SelectorPM : 0

; ****************************************************************************************


[BITS 32]
; ========================================================================================
; 保护模式代码段,由实模式跳入
Label_PM_main:
    mov ax, SelectorVideo
    mov gs, ax
    mov edi, (80 * 5 + 35) * 2
    mov ah, 0xC
    mov al, ‘O‘
    mov [gs : edi], ax
    mov al, ‘K‘
    mov [gs : edi + 2], ax

    jmp $

; ****************************************************************************************


; ========================================================================================
; FAT12 文件系统引导扇区引导代码的剩余部分用 0 填满
    times 510 - ($ - $$) db 0

; ****************************************************************************************


; ========================================================================================
; FAT12 文件系统引导扇区的的结束标志(最后 2 字节,必须是 0xAA55)
    dw 0xAA55

; ****************************************************************************************

; ========================================================================================
    CodeLenOfPM     equ $ - Label_PM_main

; ****************************************************************************************

    运行下,成功!

技术分享

第十四天、试验保护模式

标签:

原文地址:http://my.oschina.net/u/580100/blog/530488

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!