⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 复件 fat32.asm

📁 自己以前写的 引导扇区代码。包括: fat12.asm fat16.asm fat32.asm
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;文 件 名:	fat16.asm
;版    本:	Beta 0.0.01
;功    能:	读入 kernel.sys	及 FAT16.DRVv(fat12) 到内存中,并执行kernel.sys
;编    译:	nasm -fbin fat16.asm -o	fat16.bin
;程    序:	姜勇/sevek/sevekwl
;注    释:	姜勇/sevek/sevekwl
;说    明:
;	|-----------------------|0000:0000
;	|			|
;	|	中断向量表	|
;	|			|
;	|-----------------------|0000:0400
;	|	BIOS数据区	|
;	|-----------------------|0000:0500
;	|			|
;	|			|
;	|			|0000:2BF0 之上的区域为kernel.sys与fat16.drv的Fat链表
;	|			|0000:2BF4 FAT16.DRV的首簇号;执行SaveFat后为首指针
;	|	 引导记录	|0000:2BF8 Kernel.sys的首簇号;执行SaveFat后为首指针
;	|	 堆栈区域	|0000:2BFC 磁盘数据区起始位置
;	|			|0000:2BF0 根目录占用扇区数
;	|			|0000:2BF4 根目录起始扇区号
;	|			|0000:2BF8 Fat表起始扇区号
;	|			|0000:2BFC 驱动器号
;	|-----------------------|0000:2C00
;	|      Fat16引导代码	|
;	|-----------------------|0000:8400
;	|      Fat16引导代码	|
;	|-----------------------|1000:0000
;	|			|该地址区域在装载文件之
;	|	KERNEL.SYS	|前用于临时存放	FAT 表
;	|			|及根目录文件登记表等
;	|-----------------------|5000:0000
;	|	FAT16.DRV	|
;	|-----------------------|
;	|			|
;	|			|
;							1010部落姜勇
;						      于2006年12月24日
;==================================================================================
%include	".\language\chinese.inc"
%define		Seg_CS_Boot	0x1000		;KERNEL.SYS代码段地址
%define		Seg_FS_Boot	0x5000		;FAT16.DRV代码段地址
%define		Reg_IP_Base	0x7C00		;引导扇区代码在内存中的偏移地址
%define		Flag_Offset	0x1fc		;引导扇区标志偏移地址
%define		Flag_BootSect	0xaa55		;引导扇区标志字
%define		ReadOneSector	0x0201		;读一扇区的功能号
%define		OtherSectors	2		;引导程序共占几个扇区
%define		fNameSize	11		;文件名长度为11字节
%define		COUNT_Retry	5		;发生错误的重试次数
%define		proc
%define		endp
;==================================================================================
org Reg_IP_Base
real_boot:
;==================================================================================
		jmp	short	BootStart	;跳转指令,转到0000:7C3E
		nop
;==================================================================================
;软盘BPB表的数据定义
@OemStr		DB	'MSWIN4.1'	;			8字节
SectSize	DW	0x200		; 字节/扇区		2字节
SectOfCurs	DB	8		; 每个簇占用扇区数	1字节
ResaveSect	DW	32		; 保留扇区数		2字节
FatOfDisk	DB	2		; 有几个FAT表		1字节
FileOfRoot	DW	0		; Fat32未使用		2字节
SectOfDisk	DW	0		; Fat32未使用		2字节
DiskType	DB	0f8h		; 磁盘介质描述:		1字节
SectPreFat	DW	0		; Fat32未使用		2字节
SectOfCly	DW	0x3f		; 每道扇区数		2字节
DiskHeads	DW	0x20		; 磁盘柱面数		2字节
HidSectors	DD	0x3f		; 隐含扇区数		4字节
AllSectors	DD	0x1ee241	; 大容量磁盘的总扇区数	4字节
;Fat32 Information definition
F32_SectPreFat	DD	0x07b7		; FAT表占用的扇区数	4字节
F32_Flags	DW	0		; 标志			2字节
F32_Version	DW	0		; 版本号		2字节
F32_Root1stCur	DD	2		; 根目录所在的首簇号	4字节
F32_Infor	DW	1		; 文件系统信息扇区	2字节
F32_BootBak	DW	6		; 引导扇区备份		2字节
F32_ResData	Times	0x0c	db	0
					; 保留			c字节
NOfDriver	DB	0x80		; BIOS驱动器号
ExtBootFlag	DB	0x2900		; 扩展引导标志
SerNumber	DD	0x27361ddf	; 磁盘序列号		4字节
@DiskVolume	DB	'FANS BOOT01'	; 磁盘卷标		11字节
@FatType	DB	'FAT32   '	; 文件分配表类型	8字节
;==================================================================================
BootStart:
		mov	bp,	Reg_IP_Base		;在该程序中,除发生错误外
							;	       BP==0x7C00
		mov	bx,	cs
		cli
		mov	ss,	bx
		mov	sp,	bp
		sti
		push	cs
		pop	ds
		push	cs
		pop	es
;==================================================================================
;检测扩展int13h
;int 0x13
;入口:				AH=0x41		功能:
;				BX=0x55aa	     检测某驱动器是否支持
;				DL=驱动器号	     扩展INT 0x13
;出口:	成功	CF=0		BIOS支持扩展INT	0x13
;		BX=0xAA55	并且该驱动器支持int 0x13的扩展功能
;		CX=子集位图	至少支持第一个子集
;	失败	CF=1
;	或	BX!=0xAA55
;	或	CL&1!=1
;==================================================================================
		mov	dl,	[NOfDriver]		;取驱动器号
		mov	ah,	0x41
		mov	bx,	0x55aa
		int	0x13
		jc	LoadSecend
		cmp	bx,	0xaa55
		jnz	LoadSecend
		test	cl,	1
		jz	LoadSecend
		mov	byte	[bp+2],	0x5a		;[BP+02]=0x5a 原为 NOP 语
							;句在此借作系统是否支持扩
							;展INT13H的标志,该标记将
							;在Read_Disk过程中被使用。
;==================================================================================
;将Boot代码的第2扇区装载到 0000:7E00 (16进制)
;==================================================================================
LoadSecend:
		mov	eax,	[bp+HidSectors-Reg_IP_Base]
							;取隐藏扇区数
		inc	eax				;第2扇区号=隐藏扇区数+1
		mov	bx,	Reg_IP_Base+0x200
		mov	cx,	1
		call	Read_Disk
		jc	SectorError
		mov	bx,	SectorFlag+1
;==================================================================================
;标志检测
;该标志为 Fans Bootsector 的固有标志,总共4字节,其值必须为46,61,55,AA
;仅检测中间2字节,即:61,55
;==================================================================================
		mov	ax,	0x5561
		cmp	ax,	[bx]
		jnz	SectorError			;标志不正确则引导失败
		jmp	near	BeginSecend
SectorError:						;错误处理
		mov	si,	ERR_DSK_EN
		push	cs
		pop	ds
.@@1:
		lodsb
		mov	ah,	0x0e
		int	0x10
		cmp	al,	'!'			;检测字符串是否结束
		jnz	.@@1				;重复操作
BootFail:						;引导失败,等待按键并重新引导
		xor	ax,	ax
		int	0x16
		int	0x18
;==================================================================================
;				|		 |
;			sp-18  >|----------------|<<<<<<< stack	low address
;				|	DS	 |
;    Packet start---->	sp-16  >|----------------|
;				|数据包大小10字节|<-----push word 0x10	2bytes
;			sp-14  >|----------------|
;				|每次循环读 1扇区|<-----push word 1	2bytes
;			sp-12  >|----------------|
;				|    偏移地址	 |<-----bx		4bytes
;			sp-08  >|----------------|
;				|	段	 |<-----es		2bytes
;			sp-06  >|----------------|
;				|   绝对扇区号	 |<-----eax		4bytes
;			sp-04  >|----------------|
;				|	0	 |<-----cs		2bytes
;			sp-02  >|----------------|
;				|	0	 |<-----cs		2bytes
;    Packet over ---->	sp     >|----------------|<<<<<<< stack	high address
;				|       DX	 |
;				|----------------|
;				|       DI	 |
;				|----------------|
;				|       SI	 |
;				|----------------|
;				|	IP	 |
;				|----------------|
;				|       CS	 |
;				|----------------|
;				|     stack	 |
;==================================================================================
;		Read_Disk	功能	读磁盘扇区
;				入口:			bp=0x2C00
;							eax=(首)扇区号
;							cx=要读的扇区数
;							es:bx=缓冲区首地址
;				出口:	成功	CF=0	eax=(尾)扇区号+1
;							cx=0
;							es:bx=缓冲区尾地址
;					失败	CF=1
;可能改变的寄存器: eax,ebx,ecx
;未改变的寄存器有: edx,ebp,esi,edi,esp,ds,es,ss
;==================================================================================
proc Read_Disk:
		push	si
		push	di
		push	dx
ExtReadNext:
		cmp	byte	[bp+2],	0x5a
		jnz	Use_OldInt13
							;使用扩展INT13H读盘,以
							;       支持大容量硬盘
		push	cs				;cs=0
		push	cs				;cs=0
		push	eax				;eax=绝对扇区号
		push	es				;读数据到指定的段
		push	bx				;段内的偏移
		push	word	1			;读多少扇区
		push	word	0x10			;说明这个数据包的大小为
							;		 16字节
		mov	si,	sp
		push	ds
		push	ss
		pop	ds				;ds:si指向数据包的位置
		push	eax
		mov	dl,	[bp+NOfDriver-Reg_IP_Base]
		mov	ah,	0x42			;扩展int13h的读盘功能号
		int	0x13				;扩展读盘
		pop	eax
		pop	ds
		jc	Extint13_Error
		add	sp,	0x10			;跳过堆栈中的数据包位置
		add	bx,	[bp+SectSize-Reg_IP_Base]
		jnc	no_inc_es			;无进位,转移
		mov	ax,	es			;有进位--->ES+1000H
		add	ah,	10h
		mov	es,	ax
no_inc_es:
		inc	eax
		loop	ExtReadNext
		jmp	short	Read_Return
Extint13_Error:
		add	sp,	0x10			;跳过堆栈中的数据包位置
		stc
Use_OldInt13:
Read_Return:
		xor	cx,	cx
		pop	dx
		pop	di
		pop	si
		ret
endp
;==================================================================================
ERR_DSK_EN	db 'Load the secend boot sector error .',0x0d,0x0a
		db 'Please insert a bootdisk and hit any key to contion !'
BootFilename	db 'KERNEL  SYS'
FileSystemDrv	db 'FAT16   DRV'
;==================================================================================
;			****引导扇区有效标志****
;						位置	 0x2C00+0x01fe(偏移)
;						数值	 0xaa55
;						说明:	 该标志为引导扇区有效
;							 标志,若为0xaa55则有
;							 效,否则BIOS认为无效
;							 且不予执行。
;						注:	 在本程序的其他扇区中
;							 则以0xaa556146作为引
;							 导扇区有效标志即:在
;							 55,AA 前加上'Fa'作为
;							 引导代码的次扇区有效
;							 标志
times Flag_Offset+2-($-$$)	db	0
					dw	Flag_BootSect
;**********************************************************************************
;			****引导代码第 2扇区****
;						位置	 位于引导扇区之后的第
;							 一扇区,由
;							   HidSectors+1
;							 可得到其物理位置
;						说明	 该部分代码用于读取其
;							 他扇区并转移控制权,
;							 其包含 
;							     PrintCh
;							 子过程可用于显示错误
;							 提示中的汉字信息
;							 另:其包含的汉字字模
;							     信息被放disk_dot
;							     开始的内存地址中
;==================================================================================
OtherInfo	db	OtherSectors			;其他引导代码占用扇区数
		dd	0x41
		dd	0x42
		dd	0x43

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -