名称 | 开始字节 | 长度 | 内容 | 参考值 |
BS_jmpBOOT | 0 | 3 | 一个短跳转指令 | jmp Label_07c00H nop |
BS_OEMName | 3 | 8 | 厂商名 | 'QingFeng' |
BPB_BytesPerSec | 11 | 2 | 每扇区字节数(Bytes/Sector) | 0x200 |
BPB_SecPerClus | 13 | 1 | 每簇扇区数(Sector/Cluster) | 0x1 |
BPB_ResvdSecCnt | 14 | 2 | Boot记录占用多少扇区 | ox1 |
BPB_NumFATs | 16 | 1 | 共有多少FAT表 | 0x2 |
BPB_RootEntCnt | 17 | 2 | 根目录区文件最大数 | 0xE0 |
BPB_TotSec16 | 19 | 2 | 扇区总数 | 0xB40[2*80*18] |
BPB_Media | 21 | 1 | 介质描述符 | 0xF0 |
BPB_FATSz16 | 22 | 2 | 每个FAT表所占扇区数 | 0x9 |
BPB_SecPerTrk | 24 | 2 | 每磁道扇区数(Sector/track) | 0x12 |
BPB_NumHeads | 26 | 2 | 磁头数(面数) | 0x2 |
BPB_HiddSec | 28 | 4 | 隐藏扇区数 | 0 |
BPB_TotSec32 | 32 | 4 | 如果BPB_TotSec16=0,则由这里给出扇区数 | 0 |
BS_DrvNum | 36 | 1 | INT 13H的驱动器号 | 0 |
BS_Reserved1 | 37 | 1 | 保留,未使用 | 0 |
BS_BootSig | 38 | 1 | 扩展引导标记(29h) | 0x29 |
BS_VolID | 39 | 4 | 卷序列号 | 0 |
BS_VolLab | 43 | 11 | 卷标 | 'QingFeng' |
BS_FileSysType | 54 | 8 | 文件系统类型 | 'FAT12' |
引导代码及其他内容 | 62 | 448 | 引导代码及其他数据 | 引导代码(剩余空间用0填充) |
结束标志0xAA55 | 510 | 2 | 第510字节为0x55,第511字节为0xAA | 0xAA55 |
把软盘上的第1个扇区(C0-H0-S1 即柱面0,磁头0,扇区1)称为引导扇区,也要知道启动区(引导扇区)内容在内存中的装载地址:0x00007c00-0x00007dff(512字节)。
1 CYLS EQU 10 2 3 ORG 0x7c00 ; 指明程序在内存中的装载地址 4 5 ; 标准FAT12格式的软盘 6 7 JMP entry ;短跳转指令 2B 8 DB 0x90 ;作用等于NOP 1B 9 DB "HARIBOTE" ;厂商名 8B 10 DW 512 ;每个扇区的大小(必须是512) 2B 11 DB 1 ;簇的大小(必须是一个扇区) 1B 12 DW 1 ;Boot记录占用多少扇区 2B 13 DB 2 ;FAT表的个数 1B 14 DW 224 ;根目录区文件最大数 2B 15 DW 2880 ;扇区总数(即该磁盘大小,必须是2880扇区) 2B 16 DB 0xf0 ;介质描述符,磁盘的种类(必须是0xf0) 1B 17 DW 9 ;FAT的长度(每个FAT表所占扇区数,必须是9) 2B 18 DW 18 ;每磁道扇区数(1个磁道有几个扇区,必须为18) 2B 19 DW 2 ;磁头数 2B 20 DD 0 ;隐藏扇区数 4B 21 DD 2880 ;重写一次磁盘的大小 4B 22 DB 0,0,0x29 ;INT 13H的驱动器号,保留未使用和扩展引用标记 2B 23 DD 0xffffffff ;卷序列号 4B 24 DB "HARIBOTEOS " ;卷标 2B 25 DB "FAT12 " ;文件系统类型 2B 26 RESB 18 ;空18字节 18B 27 28 ; 程序主体,即引导代码(剩余空间用0填充) 29 ; 到这里是0x7c50 30 entry: 31 MOV AX,0 ;寄存器初始化 32 MOV SS,AX 33 MOV SP,0x7c00 34 MOV DS,AX 35 36 37 ; 读磁盘,第二个扇区读到内存0x0820处 38 MOV AX,0x0820 39 MOV ES,AX 40 MOV CH,0 ; 柱面0 41 MOV DH,0 ; 磁头0 42 MOV CL,2 ; 扇区2 43 readloop: 44 MOV SI,0 ; 失败次数记录的寄存器 45 retry: 46 MOV AH,0x02 ; AH=0x02 (读盘) 47 MOV AL,1 ; AL=处理对象的扇区 48 MOV BX,0 ; ES:BX=缓冲地址 49 MOV DL,0x00 ; DL=驱动器号 50 INT 0x13 ; 调用BIOS0x13函数 51 JNC next ; 没出错跳转到next 52 ADD SI,1 53 CMP SI,5 54 JAE error ; SI >= 5 出错次数大于5,跳转 55 MOV AH,0x00 ; AH=0x00 (重置驱动器) 56 MOV DL,0x00 ; DL=驱动器号 57 INT 0x13 ; 调用函数0x13 58 JMP retry 59 60 ; C0-H0-S2 到C9-H1-S18的读取(读取10个柱面,启动区在C0-H0-S1,所以不读取) 61 next: 62 MOV AX,ES ; 内存地址后移512字节(1个扇区),ES2*16-ES1*16=0x200(512字节),ES2-ES1=0x20,所以让ES内的值增加0x20; 63 ADD AX,0x0020 64 MOV ES,AX ; ADD ES,0x020 65 ADD CL,1 66 CMP CL,18 67 JBE readloop ; CL <= 18 68 MOV CL,1 69 ADD DH,1 70 CMP DH,2 71 JB readloop ; DH < 2 72 MOV DH,0 73 ADD CH,1 74 CMP CH,CYLS 75 JB readloop ; CH < CYLS 76 77 78 MOV [0x0ff0],CH ; 把CYLS的值写入内存地址0x0ff0中 79 JMP 0xc200 ; 跳转到文件内容的内存地址 80 81 ; 以下全部是错误处理代码 82 error: 83 MOV SI,msg 84 putloop: 85 MOV AL,[SI] 86 ADD SI,1 ; SI寄存器内容(内存地址)+1 87 CMP AL,0 88 JE fin 89 MOV AH,0x0e 90 MOV BX,15 91 INT 0x10 92 JMP putloop 93 fin: 94 HLT 95 JMP fin 96 msg: 97 DB 0x0a, 0x0a 98 DB "load error" 99 DB 0x0a 100 DB 0101 102 RESB 0x7dfe-$ ;510字节前剩余填充0103 104 DB 0x55, 0xaa ;第510字节为0x55,第511字节为0xAA