【OS】11 – 实模式到保护模式(中)【从16位代码段进入到32位代码段,从实模式进入到保护模式】

【OS】11 – 实模式到保护模式(中)【从16位代码段进入到32位代码段,从实模式进入到保护模式】

gitee仓库传送门

保护模式的编程
从16位代码段进入到32位代码段,从实模式进入到保护模式;
inc.asm


; Segment Attribute
DA_32    equ    0x4000
DA_DR    equ    0x90
DA_DRW   equ    0x92
DA_DRWA  equ    0x93
DA_C     equ    0x98
DA_CR    equ    0x9A
DA_CCO   equ    0x9C
DA_CCOR  equ    0x9E

; Selector Attribute
SA_RPL0    equ    0
SA_RPL1    equ    1
SA_RPL2    equ    2
SA_RPL3    equ    3

SA_TIG    equ    0
SA_TIL    equ    4

; 描述符
; 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 & 0xFFFF                         ; 段界限1
    dw    %1 & 0xFFFF                         ; 段基址1
    db    (%1 >> 16) & 0xFF                   ; 段基址2
    dw    ((%2 >> 8) & 0xF00) | (%3 & 0xF0FF) ; 属性1 + 段界限2 + 属性2
    db    (%1 >> 24) & 0xFF                   ; 段基址3
%endmacro                                     ; 共 8 字节

loader.asm


%include "inc.asm"

org 0x9000

jmp CODE16_SEGMENT

[section .gdt]
; GDT definition
;第0项用来占位, 定义:          段基址,     段界限,        段属性;
GDT_ENTRY       :     Descriptor    0,            0,           0
CODE32_DESC     :     Descriptor    0,    Code32SegLen  - 1,   DA_C + DA_32

; GDT en;
GdtLen    equ   $ - GDT_ENTRY

GdtPtr:
          dw   GdtLen - 1 ;2字节的偏移
          dd   0   ;4字节的起始地址

; GDT Selector
; Code32Selector 用于访问CODE32_DESC里的成员
; CODE32_DESC 位于gdt表中的第1位。 "0x0001 << 3" 是选择子当中的段描述符索引
Code32Selector    equ (0x0001 << 3) + SA_TIG + SA_RPL0

; end of [section .gdt]

[section .s16]
[bits 16]
CODE16_SEGMENT:
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7c00

    ; initialize GDT for 32 bits code segment
    mov eax, 0
    mov ax, cs
    shl eax, 4
    add eax, CODE32_SEGMENT ;得到32位代码段的物理地址,也就是CODE32_DESC需要的段基址
    ;初始化段描述符的值,把基地址放到对应的内存地址处
    mov word [CODE32_DESC + 2], ax ; 前2个字节放到偏移为2字节地址处,低16位放到段基址
    shr eax, 16
    mov byte [CODE32_DESC + 4], al ; 第3个字节放到偏移为4字节地址处,8位
    mov byte [CODE32_DESC + 7], ah ; 第4个字节放到偏移为7字节地址处,8位

    ; initialize GDT pointer struct
    mov eax, 0
    mov ax, ds
    shl eax, 4
    add eax, GDT_ENTRY
    mov dword [GdtPtr + 2], eax;地址放到结构体GdtPtr的4字节处

    ; 1. load GDT
    lgdt [GdtPtr]

    ; 2. close interrupt
    cli 

    ; 3. open A20地址线
    in al, 0x92
    or al, 00000010b
    out 0x92, al

    ; 4. enter protect mode 把寄存器对应的bit置为1
    mov eax, cr0
    or eax, 0x01
    mov cr0, eax ; 进入32位的模式

    ; 5. jump to 32 bits code
    ; 刷新流水线,强制将之后的代码按照32位的方式来处理后续代码,这里必须强制跳转
    jmp dword Code32Selector : 0

[section .s32]
[bits 32]
CODE32_SEGMENT:
    mov eax, 0;打断点验证
    jmp CODE32_SEGMENT

Code32SegLen    equ    $ - CODE32_SEGMENT ;指定32位代码段的段界限

调试验证:

反汇编,确定地址,下断点调试
 

file

 
 
file

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇