loader.asm 注释

来源:互联网 发布:带端口的域名解析 编辑:程序博客网 时间:2024/06/06 08:31
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,cs   mov ds,ax   mov es,ax   mov ss,ax   mov sp,BaseOfStack      mov  dh,0          ;"Loading   "   call  DispStr         ;显示字串      ;下面在A盘的根目录中寻找Kernel.bin   mov  word [wSectorNo],SectorNoOfRootDirectory   xor  ah,ah   xor  dl,dl   int  13h                ;软驱复位LABEL_SEARCH_IN_ROOT_DIR_BEGIN:   cmp  word[wRootDirSizeForLoop],0       jz  LABEL_NO_KERNELBIN   ;根目录读完未找到则跳转   dec  word[wRootDirSizeForLoop]      mov  ax,BaseOfKernelFile   mov  es,ax          ; es <- BaseOfKernelFile  ES段寄存器,此处不支持立即数寻址   mov  bx,OffsetOfKernelFile  ; bx <- OffsetOfKernelFile   mov  ax,[wSectorNo]     ; ax <- Root Directory 中的某 Sector号      mov  cl,1   call  ReadSector       ; 从序号为ax的扇区开始读入cl个扇区至内存es:bx处      mov  si,KernelFileName    ; ds:si -> "KERNEL BIN"   mov  di,OffsetOfKernelFile  ; es:di -> BaseOfKernelFile   cld              ; 置DF为0,字符串操作时,si自增   mov   dx,10h         ; 循环控制数,每扇区16个条目,每条目32字节,16*32=512LABEL_SEARCH_FOR_KERNELBIN:   cmp   dx,0   jz  LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR ; 未找到则读下一个扇区   dec  dx                         mov   cx,11                   ; 循环控制数,比较文件名,长度11LABEL_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:     ; 显示未找到KERNEL   mov  dh,2   call  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+ax   add   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置前景色为0fh   int   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_LOADED   push  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   $         ; 死循环 

0 0
原创粉丝点击