作者在介紹了一個簡單的引導區程式後,就開始引入了DOS作業系統,我感覺在介紹一個從零開始的作業系統時,引入一個成型的作業系統不是一件很好的事情,因此非到萬不得已,我還是堅持在pmtest1.asm程式上改動這個作業系統的雛形,直到編譯之後的檔案體積超過了510位元組。
作者為了展示保護模式下強大的資料讀取能力,將一塊資料區放在了5M的位置,然後先寫後讀,我在pmtest1.asm的基礎上,完成了和作者幾乎一樣的功能,也能夠很好地理解保護模式下資料讀取的強大能力。其中紅色代碼部分為本程式增加內容
%include"pm.inc"; 常量, 宏, 以及一些說明org07c00hHAHA_begin:jmpLABEL_BEGINQianlen equ $-HAHA_begin[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 ; 顯存首地址LABEL_DESC_HONDATA: Descriptor 0500000h, 0ffffh, DA_DRW ; HONDATALABEL_DESC_HONMSG: Descriptor 0, 0ffffh, DA_DRW ; HONMSGGdtLenequ$ - LABEL_GDT; GDT長度GdtPtrdwGdtLen - 1; GDT界限dd0; GDT基地址SelectorCode32equLABEL_DESC_CODE32- LABEL_GDTSelectorVideoequLABEL_DESC_VIDEO- LABEL_GDTSelectorHONDATA equLABEL_DESC_HONDATA - LABEL_GDTSelectorHONMSGequLABEL_DESC_HONMSG- LABEL_GDTGDTLen1 equ $-LABEL_GDT[SECTION .HONMSG]LABEL_HONMSG:Message db "Hello world!",0OffsetMessage equ $-LABEL_HONMSG;End of [SECTION .HONDATA]HONMSGLen equ $-LABEL_HONMSG[SECTION .s16][BITS16]LABEL_BEGIN:movax, csmovds, axmoves, axmovss, axmovsp, 0100hxoreax, eaxmovax, csshleax, 4addeax, LABEL_SEG_CODE32movword [LABEL_DESC_CODE32 + 2], axshreax, 16movbyte [LABEL_DESC_CODE32 + 4], almovbyte [LABEL_DESC_CODE32 + 7], ahxoreax,eaxmovax,dsshleax, 4addeax,LABEL_HONMSGmovword [LABEL_DESC_HONMSG+2],axshreax,16movbyte[LABEL_DESC_CODE32+4],almovbyte[LABEL_DESC_CODE32+7],ahxoreax, eaxmovax, dsshleax, 4addeax, LABEL_GDT; eax <- gdt 基地址movdword [GdtPtr + 2], eax; [GdtPtr + 2] <- gdt 基地址lgdt[GdtPtr]cliinal, 92horal, 00000010bout92h, almoveax, cr0oreax, 1movcr0, eaxjmpdword SelectorCode32:0; 執行這一句會把 SelectorCode32 裝入 cs,; 並跳轉到 Code32Selector:0 處 moveax, cr0SegCode16Len equ $-LABEL_BEGIN[SECTION .s32][BITS32]LABEL_SEG_CODE32:movax, SelectorVideomovgs, ax; 視頻段選擇子(目的)mov ax, SelectorHONDATA mov es, ax ; 5M資料區段的選擇子mov ax, SelectorHONMSGmovds, ax; message 段;將MSG中的資料移動到DATA地區movedi, (80 * 10 + 0) * 2; 螢幕第 11 行, 第 79 列。xoresi,esimovah, 0Ch moval, 'A';mov[gs:edi], axcall Write movedi, (80 * 11 + 0) * 2 xoresi,esimovah, 0Chmov ecx,20h .begin: mov al,[es:esi]test al,aljz.jieshumov[gs:edi], axinc esiinc ediinc edijmp .begin.jieshu:jmp$ Write:push esipush edipush ecxxor esi,esixor edi,edimov ecx,100cld.a:lodsbtest al,aljz overstosb loop .aover:pop ecxpop edipop esiretSegCode32Lenequ$ - LABEL_SEG_CODE32; END of [SECTION .s32]times 510-(4+(GDTLen1+3)/4*4+(SegCode16Len+3)/4*4+(HONMSGLen+3)/4*4+(SegCode32Len)) db 0dw 0xAA55