|
;==================================================================== ; ; 显示一个字符串 ; 输入: ; DS:SI = 字符串的起始地址(以NULL结束) ; ;==================================================================== ShowMessage: LODSB ; AL = DS:[SI] SI = SI+1 OR AL,AL ; 检测是否遇到NULL字符串 JZ _SHOW_END MOV AH,0EH MOV BX,07H INT 10H JMP ShowMessage
_SHOW_END: RET
;==================================================================== ; 数据区 ;==================================================================== LoaderName db “FDOSLDR BIN“ ; 第二阶段启动程序 FDOSLDR.BIN 你复制的文字来自西部网安 MessageMissLoader db “NO FDOSLDR.BIN.“,0DH,0AH,00H ; 没有找到装载程序 MessageDiskError db “Disk Error.“,0DH,0AH,00 ; 磁盘错误消息 MessageRestart db “Press any key to restart.“ ,0DH,0AH,00 ; 提示重启消息
;==================================================================== ; 扇区最后的标记字节(NASM不支持重复ORG) ;==================================================================== Padding TIMES 510-($-$$) db 00H SectorSignature dw 0AA55H
;==================================================================== ; 第二个扇区的代码(该代码位于分区的第四个扇区) ;====================================================================
;==================================================================== ; 查找根目录,检查是否有 FDOSLDR.BIN文件 ;==================================================================== _SEARCH_LOADER:
; 设置缓冲区 MOV WORD [ BP - DAP_BUFFER_OFF ], DATA_BUF_OFF ; 0000:1000H
; 根目录起始扇区号 MOV EAX,DWORD[RootDirectoryStart] MOV DWORD[ BP - CURRENT_CLUSTER ],EAX
; 检查下一个簇 _NEXT_ROOT_CLUSTER:
; 根据簇号计算扇区号 DEC EAX DEC EAX ; EAX = EAX - 2 XOR EBX,EBX MOV BL, BYTE[ SectorsPerCluster] MUL EBX ADD EAX,DWORD[ BP- DATA_START_SECTOR] MOV DWORD[ BP - DAP_SECTOR_LOW ], EAX MOV DL,[SectorsPerCluster] 你复制的文字来自西部网安
; 检查下一个扇区 _NEXT_ROOT_SECTOR:
; 依次读取每个根目录扇区,检查是否存在FDOSLDR.BIN文件 CALL ReadSector
; 检查该扇区内容 MOV DI,DATA_BUF_OFF MOV BL,BYTE [ BP - DIR_PER_SECTOR]
; 检查每一个目录项 _NEXT_ROOT_ENTRY: CMP BYTE [DI],DIR_NAME_FREE JZ _MISSING_LOADER ; NO MORE DIR ENTRY
; 检查是否装载程序 PUSH DI ; 保存DI MOV SI,LoaderName MOV CX,11 REPE CMPSB JCXZ _FOUND_LOADER ; 装载Loader并运行
; 是否还有下一个目录项(内层循环) POP DI ADD DI,DIR_ENTRY_SIZE DEC BL JNZ _NEXT_ROOT_ENTRY
; 检查是否还有下一个扇区可读(外层循环) DEC DL JZ _CHECK_NEXT_ROOT_CLUSTER INC DWORD [ BP - DAP_SECTOR_LOW ] ; 增加扇区号 JMP _NEXT_ROOT_SECTOR
; 检查下一个簇 _CHECK_NEXT_ROOT_CLUSTER:
; 计算FAT所在的簇号和偏移 ; FatOffset = ClusterNum*4 XOR EDX,EDX MOV EAX,DWORD[BP - CURRENT_CLUSTER] SHL EAX,2 XOR ECX,ECX MOV CX,WORD [ BytesPerSector ] DIV ECX ; EAX = Sector EDX = OFFSET ADD EAX,DWORD [BP - FAT_START_SECTOR ] MOV DWORD [ BP - DAP_SECTOR_LOW ], EAX
; 读取扇区 CALL ReadSector 你复制的文字来自西部网安
; 检查下一个簇 MOV DI,DX ADD DI,DATA_BUF_OFF MOV EAX,DWORD[DI] ; EAX = 下一个要读的簇号 AND EAX,CLUSTER_MASK MOV DWORD[ BP - CURRENT_CLUSTER ],EAX CMP EAX,CLUSTER_LAST ; CX 〉= 0FFFFFF8H,则意味着没有更多的簇了 JB _NEXT_ROOT_CLUSTER JMP _MISSING_LOADER
;==================================================================== ; 装载FDOSLDR.BIN文件 ;==================================================================== _FOUND_LOADER: ; 目录结构地址放在DI中 POP DI XOR EAX,EAX MOV AX,[DI+OFF_START_CLUSTER_HIGH] ; 起始簇号高32位 SHL AX,16 MOV AX,[DI+OFF_START_CLUSTER_LOW] ; 起始簇号低32位 westsafe.net MOV DWORD[ BP - CURRENT_CLUSTER ],EAX MOV CX, OSLOADER_SEG ; CX = 缓冲区段地址
_NEXT_DATA_CLUSTER:
; 根据簇号计算扇区号 DEC EAX DEC EAX ; EAX = EAX - 2 XOR EBX,EBX MOV BL, BYTE[ SectorsPerCluster] MUL EBX ADD EAX,DWORD[ BP- DATA_START_SECTOR] MOV DWORD[ BP - DAP_SECTOR_LOW ], EAX MOV DL,[SectorsPerCluster]
; 设置缓冲区 MOV WORD [ BP - DAP_BUFFER_SEG ],CX MOV WORD [ BP - DAP_BUFFER_OFF ],00H
; 每个簇需要读取的扇区数 MOV BL , BYTE [SectorsPerCluster] 西部网安
_NEXT_DATA_SECTOR: ; 读取簇中的每个扇区(内层循环) ; 注意 : 通过检查文件大小,可以避免读取最后一个不满簇的所有大小 ; 读取数据扇区 CALL ReadSector
; 更新地址,继续读取 MOV AX, WORD [BytesPerSector] ADD WORD [BP - DAP_BUFFER_OFF],AX INC DWORD [BP - DAP_SECTOR_LOW] ; 递增扇区号 DEC BL ; 内层循环计数 JNZ _NEXT_DATA_SECTOR
; 检查下一个簇
; 更新读取下一个簇的缓冲区地址 MOV CL,BYTE [ SectorsPerCluster ] MOV AX ,WORD [BytesPerSector] SHR AX ,4 MUL CL ADD AX ,WORD [ BP - DAP_BUFFER_SEG ] 西部网安 MOV CX,AX ; 保存下一个簇的缓冲区段地址
;==================================================================== ; ; 检查是否还有下一个簇(读取FAT表的相关信息) ; LET N = 数据簇号 ; THUS FAT_BYTES = N*4 (FAT32) ; FAT_SECTOR = FAT_BYTES / BytesPerSector ; FAT_OFFSET = FAT_BYTES % BytesPerSector ; ;====================================================================
; 计算FAT所在的簇号和偏移 MOV EAX,DWORD [BP - CURRENT_CLUSTER] XOR EDX,EDX SHL EAX,2 XOR EBX,EBX MOV BX,WORD [ BytesPerSector ] DIV EBX ; EAX = Sector EDX = Offset 你复制的文字来自西部网安
; 设置缓冲区地址 ADD EAX,DWORD [BP - FAT_START_SECTOR ] MOV DWORD [ BP - DAP_SECTOR_LOW ], EAX MOV WORD [BP - DAP_BUFFER_SEG ], 00H MOV WORD [BP - DAP_BUFFER_OFF ], DATA_BUF_OFF ; 0000:1000H
; 读取扇区 CALL ReadSector
; 检查下一个簇 MOV DI,DX ADD DI,DATA_BUF_OFF MOV EAX,DWORD[DI] ; EAX = 下一个要读的簇号 AND EAX,CLUSTER_MASK MOV DWORD[ BP - CURRENT_CLUSTER ],EAX
共5页: 上一页 [1] [2] [3] 4 [5] 下一页
|
评论列表
用户名: (新注册) 密码: 匿名评论