欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

loader.asm 注释

发布时间:2025/6/15 编程问答 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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 注释的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。