loader.asm 注释
生活随笔
收集整理的這篇文章主要介紹了
loader.asm 注释
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
org 100h ; 程序加載到內存100h處執行
BaseOfStack equ 0100h ; 定義Stack基址BaseOfKernelFile equ 08000h ; Kernel.bin被加載到的位置 ---段地址
OffsetOfKernelFile equ 0h ; Kernel.bin被加載到的位置 ---偏移地址jmp LABEL_START ; Start%include "fat12hdr.inc" ; 定義程序中使用的參數
LABEL_START: ; 從這里開始mov ax,csmov ds,axmov es,axmov ss,axmov sp,BaseOfStackmov dh,0 ;"Loading "call DispStr ;顯示字串;下面在A盤的根目錄中尋找Kernel.binmov word [wSectorNo],SectorNoOfRootDirectoryxor ah,ahxor dl,dlint 13h ;軟驅復位
LABEL_SEARCH_IN_ROOT_DIR_BEGIN:cmp word[wRootDirSizeForLoop],0 jz LABEL_NO_KERNELBIN ;根目錄讀完未找到則跳轉dec word[wRootDirSizeForLoop]mov ax,BaseOfKernelFilemov es,ax ; es <- BaseOfKernelFile ES段寄存器,此處不支持立即數尋址mov bx,OffsetOfKernelFile ; bx <- OffsetOfKernelFilemov ax,[wSectorNo] ; ax <- Root Directory 中的某 Sector號mov cl,1call ReadSector ; 從序號為ax的扇區開始讀入cl個扇區至內存es:bx處mov si,KernelFileName ; ds:si -> "KERNEL BIN"mov di,OffsetOfKernelFile ; es:di -> BaseOfKernelFilecld ; 置DF為0,字符串操作時,si自增mov dx,10h ; 循環控制數,每扇區16個條目,每條目32字節,16*32=512
LABEL_SEARCH_FOR_KERNELBIN:cmp dx,0jz LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR ; 未找到則讀下一個扇區dec dx mov cx,11 ; 循環控制數,比較文件名,長度11
LABEL_CMP_FILENAME:cmp cx,0 jz LABEL_FILENAME_FOUND ; 若CX為0,則表示找到,跳轉dec cx lodsb ; 將ds:si處內容傳送置AL中,si<-si+1 cmp al,byte [es:di] ; 將取出的字符與es:di處文件名相較jz LABEL_GO_ON ; 相等則跳轉到LABEL_GO_ON,比較下一個字符jmp LABEL_DIFFERENT ; 不等則跳轉到LABEL_DIFFERENT,比較下一個條目
LABEL_GO_ON:inc di ; di自增,指向下一個字符jmp LABEL_CMP_FILENAME ; 繼續比較
LABEL_DIFFERENT:and di,0FFE0h ; 0FFE0h=0b1111111111100000 ,將DI低五位清零,每個條目為32字節,使di指向本條目的開頭add di,20h ; 20h=32,指向下一個條目的開頭mov si,KernelFileName ; 將si重置為指向KernelFileName的開頭jmp LABEL_SEARCH_FOR_KERNELBIN ;跳轉到LABEL_SEARCH_FOR_KERNELBIN,從下一條目中開始查找LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR: ;查找下一個扇區add word[wSectorNo],1 ; 將wSectorNo存放值加1,指向下一個扇區jmp LABEL_SEARCH_IN_ROOT_DIR_BEGIN ;跳轉到LABEL_SEARCH_IN_ROOT_DIR_BEGIN,讀取下一個扇區并重復以上查找操作LABEL_NO_KERNELBIN: ; 顯示未找到KERNELmov dh,2call DispStr ; 輸出字串:NO KERNEL."jmp $ ; 未找到Kernel.bin,死循環LABEL_FILENAME_FOUND: ; 找到文件后的操作mov ax,RootDirSectors ; ax寄存器暫存根目錄區大小and di,0ffe0h ; di低五位清零,根目錄每個條目占32字節,將di ->當前條目的開始,書中寫and di,0fff0h,個人感覺有錯誤 push eax ; eax進棧保存mov eax,[es:di+01ch] mov dword[dwKernelSize],eax ; 保存此Kernel.bin文件大小pop eax ; 恢復eax為根目錄區大小add di,01ah ; di-> 此條目對應的開始簇號mov cx,word [es:di] ; cx保存起始簇號(扇區)push cx ; 進棧保存此Sector在FAT中的序號, 與下文調用讀取扇區的“call ReadSector"后的pop ax 相對應add cx,ax ; cx <- cx+axadd cx,DeltaSectorNo ; cx <- cx+DeltaSectorNo ,cx寄存器中內容為Kernel.bin的起始扇區號,DeltaSectorNo=17 mov ax,BaseOfKernelFile mov es,ax ; es <- BaseOfKernelFile es寄存器中存儲Kernel.bin在內存中加載的位置mov bx,OffsetOfKernelFile ; bx < - OffsetOfKernelFile bx寄存器中存儲Kernel.bin在內存中相對于基址的偏移地址mov ax,cx ; 將CX寄存器中的值賦給AX,下面將AX寄存器中指向的扇區加載進內存LABEL_GOON_LOADING_FILE: push ax ; ax進棧保存push bx ; bx進棧保存mov ah,0eh ; 置ah為0eh,int 10h調用功能為顯示字符(光標前移)mov al,'.' ; 置輸出字符'.'至al中mov bl,0fh ; bl置前景色為0fhint 10h ; 調用10h中斷,每讀一個扇區就在"Loading "后面打一個點,形成”Loading ...“的效果pop bx ; bx出棧。存放內容為Kernel.bin在相對于基址的偏移地址pop ax ; ax出棧,存放內容為Kernel.bin的起始扇區號mov cl,1 ; ReadSector的參數cl置1,表示讀取從ax處開始的一個扇區call ReadSector ; 調用ReadSector,將Kernel.bin文件加載到內存BaseOfKernelFiel:OffsetOfkernelFile處pop ax ; 與上文的push cx相對應call GetFATEntry ; 調用GetFATEntry 找到序號為AX的Sector在FAT中的條目cmp ax,0fffh jz LABEL_FILE_LOADED ; 比較 ax與0fffh的值,相等則表示此簇已經是最后一個,Kernel.bin已加載到內存,跳轉到LABEL_FILE_LOADEDpush ax ; ax進棧保存mov dx,RootDirSectors ; dx 暫存根目錄扇區數add ax,dx ; ax+=dx;add ax,DeltaSectorNo ; 計算 ax簇號對應扇區號add bx,[BPB_BytsPerSec] ; bx<-bx+[BPB_BytsPerSec],es:bx指向下一段未使用的內存jmp LABEL_GOON_LOADING_FILE ; 無條件轉移至LABEL_GOON_LOADING_FILE,進行讀取ax扇區至es:bx處的操作
LABEL_FILE_LOADED:call KillMotor ;關閉軟驅馬達mov dh,1 ; “Ready."call DispStr ; "顯示字符串"jmp $ ; 死循環
總結
以上是生活随笔為你收集整理的loader.asm 注释的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Int 10 中断功能 详解
- 下一篇: 保护模式及其编程——实模式与保护模式的切