2010年02月28日

;%define _BOOT_DEBUG_
%ifdef _BOOT_DEBUG
 org 0100h
%else
   org 07c00h
%endif
;==================================================================
%ifdef _BOOT_DEBUG_
BaseOfStack equ 0100h ;调试状态下堆栈基地址(栈底,从这个位置向低地址生长0
%else 
BaseOfStack equ 07c00h ;堆栈基地址
%endif

BaseOfLoader  equ 09000h ;Loader.bin被加载到的段地址
OffsetOfLoader  equ 0100h ;Loader.bin被加载到的偏移地址
RootDirSectors  equ 14 ;根目录占用空间
SectorNoOfRootDirectory equ 19 ;RootDirectory的第一个扇区号
SectorNoOfFAT1  equ ;FAT的第一个扇区号 = BPB_RsvSecCnt
DeltaSectorNo  equ 17
 jmp short LABEL_START
 nop ;nop不能少,估计要初始化下面的BPB磁头
;下面是FAT12磁头
 BS_OEMName DB 'LZYSTART' ; OEM String, 必须 8 个字节
 BPB_BytsPerSec DW 512  ; 每扇区字节数
 BPB_SecPerClus DB 1  ; 每簇多少扇区
 BPB_RsvdSecCnt DW 1  ; Boot 记录占用多少扇区
 BPB_NumFATs DB 2  ; 共有多少 FAT 表
 BPB_RootEntCnt DW 224  ; 根目录文件数最大值
 BPB_TotSec16 DW 2880  ; 逻辑扇区总数
 BPB_Media DB 0xF0  ; 媒体描述符
 BPB_FATSz16 DW 9  ; 每FAT扇区数
 BPB_SecPerTrk DW 18  ; 每磁道扇区数
 BPB_NumHeads DW 2  ; 磁头数(面数)
 BPB_HiddSec DD 0  ; 隐藏扇区数
 BPB_TotSec32 DD 0  ; 如果 wTotalSectorCount 是 0 由这个值记录扇区数
 BS_DrvNum DB 0  ; 中断 13 的驱动器号
 BS_Reserved1 DB 0  ; 未使用
 BS_BootSig DB 29h  ; 扩展引导标记 (29h)
 BS_VolID DD 0  ; 卷序列号
 BS_VolLab DB 'OrangeS0.02'; 卷标, 必须 11 个字节
 BS_FileSysType DB 'FAT12  ; 文件系统类型, 必须 8个字节 

LABEL_START:  mov ax,cx
   mov ds,ax
   mov es,ax
   mov ss,ax
   mov sp,BaseOfStack
   ;清屏
   mov ax,0600h
   mov bx,0700h
   mov cx,0
   mov dx,0184fh
   int 10h

   mov dh,0
   call DispStr

   xor ah,ah ;软驱
   xor dl,dl ;复
   int 13h  ;位
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;下面在A盘的根目录寻找LOADER.BIN
   
 mov word [wSectorNo],SectorNoOfRootDirectory
LABEL_SEARCH_IN_ROOT_DIR_BEGIN:
 cmp word [wRootDirSizeForLoop],0 ;判断根目录区是不是已经读完
 jz LABEL_NO_LOADERBIN
 dec word [wRootDirSizeForLoop]
 mov ax,BaseOfLoader
 mov es,ax    ;es <- BaseOfLoader
 mov bx,OffsetOfLoader  ;bx <- OffsetOfLoader
 mov ax,[wSectorNo]   ;ax <-Root Directory 中的某Sector号
 mov cl,1
 call ReadSector

 mov si,LoaderFileName  ;ds:si ->"LOADER  BIN"
 mov di,OffsetOfLoader  ;es:do ->BaseOfLoader : 0100
 cld
 mov dx,10h    ;每扇区有16个条目,每条目有32个字节
LABEL_SEARCH_FOR_LOADERBIN:
 cmp dx,0
 jz LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR
 dec dx
 mov cx,11
LABEL_CMP_FILENAME:
 cmp cx,0
 jz LABEL_FILENAME_FOUND
 dec cx
 lodsb
 cmp al,byte [es:di]
 jz LABEL_GO_ON
 jmp LABEL_DIFFERENT
LABEL_GO_ON:
 inc di
 jmp LABEL_CMP_FILENAME
LABEL_DIFFERENT:
 and di,0FFE0H ;让di指向条目开头,即32的倍数
 add di,20h  ;指向下一个条目
 mov si,LoaderFileName
 jmp LABEL_SEARCH_FOR_LOADERBIN

LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR:
 add word [wSectorNo],1
 jmp LABEL_SEARCH_IN_ROOT_DIR_BEGIN

LABEL_NO_LOADERBIN:
 mov dh,2  ;"No Loader."
 call DispStr  ;显示字符串
%ifdef _BOOT_DEBUG_
 mov ax,4c00h
 int 21h
%else 
 jmp $
%endif
LABEL_FILENAME_FOUND:
 mov ax,RootDirSectors
 and di,0ffe0h
 add di,01Ah ;di->首Sector,即每条目的第26位后的一个字节写的是fat号
 mov cx,word [es:di]
 push cx
 add cx,ax
 add cx,DeltaSectorNo
 mov ax,BaseOfLoader
 mov es,ax
 mov bx,OffsetOfLoader
 mov ax,cx
LABEL_GOON_LOADING_FILE:
 push ax
 push bx
 mov ah,0Eh
 mov al,'.'
 mov bl,0Fh
 int 10h
 pop bx
 pop ax

 mov cl,1
 call ReadSector
 pop ax
 call GetFATEntry
 cmp ax,0fffh
 jz LABEL_FILE_LOADED
 push ax
 mov dx,RootDirSectors
 add ax,dx
 add ax,DeltaSectorNo
 add bx,[BPB_BytsPerSec]
 jmp LABEL_GOON_LOADING_FILE
LABEL_FILE_LOADED:
 mov dh,1
 call DispStr
 jmp BaseOfLoader:OffsetOfLoader

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..
;变量
wRootDirSizeForLoop dw RootDirSectors ;Root Directory占用的扇区数
      ;在循环中会递减至0
wSectorNo  dw  ;要读取的扇区号
bOdd   db  ;奇数还是偶数

;字符串
LoaderFileName  db "LOADER  BIN",0 ;Loader.bin文件名
MessageLength  equ 9
BootMessage:  db "Booting  "
Message1  db "Ready.   "
Message2  db "NO LOADER"
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;显示字符串,函数开始时dh中应该是字符串序号(0-based)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  DispStr:
       mov ax,MessageLength
      mul dh
      add ax,BootMessage
       mov bp,ax
       mov ax,ds
      mov es,ax
       mov cx,MessageLength
      mov ax,01301h
       mov bx,0007h
       mov dl,0
       int 10h
       ret
 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.
;函数名:ReadSector ,从第ax个Sector开始,将cl个Sector读入 es:bx中
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ReadSector:
 push bp
 mov bp,sp
 sub esp,2
 mov byte [bp-2],cl
 push bx
 mov bl,[BPB_SecPerTrk]
 div bl
 inc ah ;z++ 为起始扇区号
 mov cl,ah ;cl <-起始扇区号
 mov dh,al ;dh<-y
 shr al,1 ;y>>1
 mov ch,al ;ch<-柱面号
 and dh,1 ;磁头号
 pop bx
 ;所需信息全部得到
 mov dl,[BS_DrvNum] ;驱动器号
.GoOnReading:
 mov ah,2 ;读
 mov al,byte [bp-2] ;读al个扇区数
 int 13h
 jc .GoOnReading ;如果读取错误CF被置为1

 add esp,2
 pop bp

 ret
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;函数名: GetFATEntry
功能:找到序号为ax的Sector在FAT中的条目并保存到ax中
由于读FAT的扇区要用到es,bx,所以保存了es,bx
GetFATEntry:
 push es
 push bx
 push ax
 mov ax,BaseOfLoader
 sub ax,0100h ;在BaseOfLoader后面留出4k空间用于存放FAT
 mov es,ax
 pop ax
 mov byte [bOdd],0
 mov bx,3
 mul bx
 mov bx,2
 div bx
 cmp dx,0
 jz LABEL_EVEN
 mov byte [bOdd],1
LABEL_EVEN: ;偶数
 xor dx,dx
 mov bx,[BPB_BytsPerSec]
 div bx
 push dx
 mov bx,0
 add ax,SectorNoOfFAT1
 mov cl,2
 call ReadSector
 pop dx
 add bx,dx
 mov ax,[es:bx]
 cmp byte [bOdd],1
 jnz LABEL_EVEN_2
 shr ax,4
LABEL_EVEN_2:
 and ax,0fffh
LABEL_GET_FAT_ENRY_OK:
 pop bx
 pop es
 ret
   times 510 - ($-$$) db 0
   dw 0xaa55

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值