日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

操作系统开发系列—2.进入32位保护模式

發(fā)布時(shí)間:2025/6/15 windows 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统开发系列—2.进入32位保护模式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

源碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 ; ========================================== ; pm.asm ; 編譯方法:nasm pm.asm -o pm.bin ; ========================================== %include??? "pm.inc"??? ; 常量, 宏, 以及一些說明 org 07c00h ????jmp LABEL_BEGIN [SECTION .gdt] ; 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??????? ; 顯存首地址 ; GDT 結(jié)束 GdtLen????? equ $ - LABEL_GDT?? ; GDT長度 GdtPtr????? dw? GdtLen - 1? ; GDT界限 ????????????????????dd? 0?????? ; GDT基地址 ; GDT 選擇子 SelectorCode32????? equ LABEL_DESC_CODE32?? - LABEL_GDT SelectorVideo?????? equ LABEL_DESC_VIDEO??? - LABEL_GDT ; END of [SECTION .gdt] [SECTION .s16] [BITS?? 16] LABEL_BEGIN: ????mov ax, cs ????mov ds, ax ????mov es, ax ????mov ss, ax ????mov sp, 0100h ????; 初始化 32 位代碼段描述符 ????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 ????; 為加載 GDTR 作準(zhǔn)備 ????xor eax, eax ????mov ax, ds ????shl eax, 4 ????add eax, LABEL_GDT????? ; eax <- gdt 基地址 ????mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址 ????; 加載 GDTR ????lgdt??? [GdtPtr] ????; 關(guān)中斷 ????cli ????; 打開地址線A20 ????in? al, 92h ????or? al, 00000010b ????out 92h, al ????; 準(zhǔn)備切換到保護(hù)模式 ????mov eax, cr0 ????or? eax, 1 ????mov cr0, eax ????; 真正進(jìn)入保護(hù)模式 ????jmp dword SelectorCode32:0? ; 執(zhí)行這一句會(huì)把 SelectorCode32 裝入 cs, ????????????????????; 并跳轉(zhuǎn)到 SelectorCode32:0? 處 ; END of [SECTION .s16] [SECTION .s32]; 32 位代碼段. 由實(shí)模式跳入. [BITS?? 32] LABEL_SEG_CODE32: ????mov ax, SelectorVideo ????mov gs, ax????????? ; 視頻段選擇子(目的) ????mov ecx, 28 ????mov edi, 0 ????mov bx, BootMessage .show: ????mov ah, 0Ch???????? ; 0000: 黑底??? 1100: 紅字 ????mov al, [bx] ????mov [gs:edi], ax ????inc edi ????inc edi ????inc bx ????loop .show ????; 到此停止 ????jmp $ BootMessage:??????? db? "Joey, I'm in protected mode!" SegCode32Len??? equ $ - LABEL_SEG_CODE32 ; END of [SECTION .s32]

運(yùn)行結(jié)果如下:

源碼解析:

1.首先程序跳轉(zhuǎn)至LABEL_BEGIN處,jmp LABEL_BEGIN。將ds、es、ss段寄存器全部初始化為當(dāng)前代碼段。

2.初始化32位代碼段描述符

在實(shí)模式下,也就是8086的16位的CPU的尋址方式是段x16+偏移,而在保護(hù)模式下,段寄存器值變成了一個(gè)索引,這個(gè)索引指向段描述符,也就是GDT中對(duì)應(yīng)的那個(gè)描述符,描述符中包含了最終的基地址。

?38-41行表示將當(dāng)前程序代碼段左移4位也就是x16,再加上LABEL_SEG_CODE32的偏移地址,最終形成LABEL_SEG_CODE32的物理地址,42-45表示把此物理地址加載到段描述符對(duì)應(yīng)的段基址位置,段描述符格式如下圖所示

段基地址0-15位也就是LABEL_DESC_CODE32 + 2地址處,將16位的ax傳入,第43行向右移動(dòng)16位表示已經(jīng)傳入的16位消除,然后將剩余的兩個(gè)8位高低寄存器值傳入對(duì)應(yīng)的段基地址處。

Descriptor是在pm.inc中定義的宏,如下圖所示,表示的就是段描述符的格式:

3.加載GDTR,GDRT的結(jié)構(gòu)圖如下所示

GDTR是唯一的一個(gè)指向段描述符表的寄存器,48-55行就是把段描述符表的基地址加載到GDTR寄存器當(dāng)中。48行清除eax值,49-52是把LABEL_GDT的物理地址加載到20行的GdtPtr的雙字處,也就是GDT基地址。55行把GdtPtr地址的內(nèi)容加載到GDTR,雙字節(jié)dw對(duì)應(yīng)的是16位界限,雙字dd對(duì)應(yīng)的是32位基地址。

4.關(guān)中斷和打開A20

保護(hù)模式下中斷處理機(jī)制和實(shí)模式不同,所以先關(guān)閉中斷,指令為cli。打開A20為歷史原因防止偏移超出最大值時(shí)回滾。58-63行

5.切換到保護(hù)模式

只要把寄存器cr0的第0位置為1就行了。66-68行

6.真正進(jìn)入保護(hù)模式的代碼段

jmp dword SelectorCode32:0,這一行是真正進(jìn)入保護(hù)模式的代碼,SelectorCode32是個(gè)段選擇子,段選擇子的作用是找到對(duì)應(yīng)的段描述符從而找到對(duì)應(yīng)的段基地址。段選擇子的格式如下圖所示

從位3開始表示為段描述符表的索引,這句代碼執(zhí)行完之后就會(huì)把描述符LABEL_DESC_CODE32中的段基址也就是LABEL_SEG_CODE32加載到cs。

dword的作用是因?yàn)楫?dāng)前還是16位的代碼,如果沒有dword,SelectorCode32:0的偏移地址如果超出16位那么只會(huì)截取16位。

到此已經(jīng)完全進(jìn)入32位保護(hù)模式的代碼了。

7.顯示字符

接下來就會(huì)跳轉(zhuǎn)到LABEL_SEG_CODE32處運(yùn)行指令了,80-81行把段選擇子SelectorVideo傳入段寄存器gs中,也就是描述符LABEL_DESC_VIDEO的段基地址0B8000h,這就是顯存的基地址。84行edi是顯存的偏移地址,87-88行是字符及字符屬性,89行為最終顯示字符。

8.描述符屬性

代碼段的屬性是DA_C + DA_32,根據(jù)pm.inc中的定義,DA_C是98h

對(duì)應(yīng)的二進(jìn)制為10011000。根據(jù)第2條的格式,DA_C其實(shí)是上面的第8-15位,第15位P是1表明這個(gè)段在內(nèi)存中存在,S位是1表明這個(gè)段是代碼段或數(shù)據(jù)段,TYPE為1000也就是8表明這個(gè)段是只執(zhí)行的代碼段,TYPE格式如下圖所示

DA_32是4000h,

4000h為100000000000000,表明是從上面的位8開始計(jì)算的后面15位也就是D/B位為1,表明這個(gè)段是32位的代碼段。

總結(jié)

以上是生活随笔為你收集整理的操作系统开发系列—2.进入32位保护模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。