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

📄 fat12.asm

📁 自己以前写的 引导扇区代码。包括: fat12.asm fat16.asm fat32.asm
💻 ASM
字号:
;文件名:	fat12.asm
;版  本:	test 0.06.12.7
;功  能:	读入 kernel.sys 及 FAT12.DRV(fat12) 到内存中,并执行kernel.sys
;编  译:	nasm -fbin fat12.asm -o fat12.bin
;说  明:
;		|-----------------------|0000:0000
;		|			|
;		|	中断向量表	|
;		|			|
;		|-----------------------|0000:0400
;		|	BIOS数据区	|
;		|-----------------------|0000:0500
;		|			|
;		|			|
;		|			|0000:7BF0 之上的区域为kernel.sys与FAT12.DRV的Fat链表
;		|			|0000:7BF2 [BP-14]  FAT12.DRV的首簇号;执行Get_FileFat后为首指针
;		|	 引导记录	|0000:7BF4 [BP-12]  Kernel.sys的首簇号;执行Get_FileFat后为首指针
;		|	 堆栈区域	|0000:7BF6 [BP-10]  磁盘数据区起始位置
;		|			|0000:7BF8 [BP-08]  根目录占用扇区数
;		|			|0000:7BFA [BP-06]  根目录起始扇区号
;		|			|0000:7BFC [BP-04]  Fat表起始扇区号
;		|			|0000:7BFE [BP-02]  驱动器号
;		|-----------------------|0000:7C00 [BP-00]
;		|      Fat12引导扇区	|
;		|-----------------------|0000:7E00
;		|			|
;		|	空--未使用	|
;		|			|
;		|-----------------------|1000:0000
;		|			|该地址区域在装载文件之
;		|	KERNEL.SYS	|前用于临时存放 FAT 表
;		|			|及根目录文件登记表等
;		|-----------------------|5000:0000
;		|	  FAT12.DRV	|
;		|-----------------------|
;		|			|
;		|			|
;==================================================================================

%include	".\inc\define.inc"
%include	".\inc\bootfile.inc"
org 0x7c00
;==================================================================================
	jmp short BootStart			;jmp short 0x7C3E
	nop
;==================================================================================
;软盘BPB表的数据定义
@OemStr		DB	'FANOS0.1'	;			8字节
SectSize	DW	512		; 字节/扇区		2字节
SectOfCurs	DB	1		; 每个簇占用扇区数	1字节
ResaveSect	DW	1		; 保留扇区数		2字节
FatOfDisk	DB	2		; 有几个FAT表		1字节
FileOfRoot	DW	224		; 根目录文件个数	2字节
SectOfDisk	DW	0B40H		; 磁盘总扇区数		2字节
DiskType	DB	0f0h		; 磁盘介质描述:		1字节
SectPreFat	DW	9		; 每个FAT占用扇区数	2字节
SectOfCly	DW	18		; 每道扇区数		2字节
DiskHeads	DW	2		; 磁盘柱面数		2字节
HidSectors	DD	0		; 隐含扇区数		4字节
AllSectors	DD	0		; 大容量磁盘的总扇区数	4字节
NOfDriver	DB	00h		; 驱动器号		1字节
ExtBootFlag	DW	29H		; 扩展引导标志		2字节
SerNumber	DD	0		; 磁盘序列号		4字节
@DiskVolume	DB	'FANS BOOT  '	; 磁盘卷标		11字节
@FatType	DB	'FAT12   '	; 文件分配表类型	8字节
;==================================================================================
BootStart:
	mov	bp,	Reg_IP_Base
	mov	ax,	cs
	mov	ss,	ax
	mov	sp,	bp
	push	dx				; SP = 0x7bfe
						; [BP-02]  <-  driver number
	mov	si,	Fat12_StartMSG
	call	Put_Char
;==================================================================================
;获取磁盘中文件系统信息
	mov	si,	[bp+HidSectors-0x7c00]	;
	add	si,	[bp+ResaveSect-0x7c00]	; SI = Start Fat
	push	si				; SP = 0x7bfc
						; [BP-04]  <-  Start Fat
						;
	sub	ax,	ax
	mov	al,	[bp+FatOfDisk-0x7c00]	;
	mul	word	[bp+SectPreFat-0x7c00]	;
	add	si,	ax			; SI = Start Root
	push	si				; SP = 0x7BFA
						; [BP-06]  <-  Start Root
	mov	ax,	[bp+FileOfRoot-0x7c00]	;
	mov	bx,	[bp+SectSize-0x7c00]	;
	shr	bx,	5			; BX / 32
	cwd
	div	bx				; AX = \
						; 根目录占用扇区数=\
						; (根目录文件数 * 每文件登记项大小|32字节|)\
						; / 每扇区字节数|512字节|=\
						; 根目录文件数 / (每扇区字节数 / 每文件登记项大小)
	push	ax				; SP = 0x7BF8
						; [BP-08]  <-  Sector pre root
	add	si,	ax			; SI= start data
	push	si;				; SP = 0X7BF6 
						; [BP-10]  <- Start data
;==================================================================================
;查找文件
	mov	ax,	[bp-6]
	mov	di,	[bp-8]			; DS = CS = 0
	push	word	Seg_CS_Boot
	pop	es				; ES = Seg_CS_Boot
	xor	bx,	bx
	call	Read_disk
	jc	Error_DiskRead
	mov	si,BootFilename
	call	find_File
	push	ax				; SP - 0X7BF4
						; [BP-12]  <-  KERNEL.SYS 的首簇号
	jc	Error_FileKernel
	mov	si,FileSystemDrv
	call	find_File
	push	ax				; SP = 0X7BF2
						; [BP-14]  <-  FAT12.DRV的首簇号
	jc	Error_FileFsdrv
;==================================================================================
;读文件分配表到缓冲区
	mov	di,	[bp+SectPreFat-0x7c00]
	mov	ax,	[bp-4]
	xor	bx,	bx
	call	Read_disk
	jc	Error_DiskRead
	mov	ax,	[bp-12]			; 取Kernel.sys 的首簇号
	mov	bx,	sp
	dec	bx
	dec	bx				; BX = BP - 16
	mov	[bp-12],bx			; [bp-12]  =  kernel.sys fat group
	push	es				; ES = Seg_CS_Boot
	pop	ds				; DS = Seg_CS_Boot
	call	Get_FileFat
	mov	ax,	[bp-14]			; 取FAT12.DRV的首簇号
	mov	bx,	sp
	dec	bx
	dec	bx
	mov	[bp-14],bx			; [BP-14]  =  fs.drv fat group
	call	Get_FileFat
;==================================================================================
;读文件
	mov	si,	[bp-12]			; SI -> kernel.sys fat group
	call	Load_file
	jc	Error_FileKernel
	mov	si,[bp-14]			; si -> fs.drv fat group
	push	word	Seg_FS_Boot
	pop	es
	call	Load_file
	jc	Error_FileFsdrv
	mov	dx,	[bp-2]
	db	0xea
	dw	0x0,Seg_CS_Boot+0x20
;==================================================================================
Error_DiskRead:
	mov	si,	Msg_ErrReadisk
	jmp	short	boot_error
Error_FileFsdrv:
	mov	si,	ERR_DRV
	jmp	short	boot_error
Error_FileKernel:
	mov	si,	ERR_KNL
	jmp	short	boot_error
boot_error:
	call	Put_Char
	mov	si,	Fat12_ERRMSG
	call	Put_Char
	xor	ax,		ax
	int	0x16
	int	0x18

;==================================================================================
Put_Char:
	push	cs
	pop	ds
next_put:
	lodsb					;从 ds:si中读入一个字符到 al
	or	al,al				;检测字符是否为0
	jz	put_return			;显示完毕, 退出过程
	mov	ah,0x0e
	mov	bl,9
	int	0x10
	jmp	short	next_put		;重复操作
put_return:
	ret
;======================================================================================
;Load_file:	装入文件	入口	SI = 文件的FAT连表地址(反向)
;======================================================================================
Load_file:
	push	ss
	pop	ds				; DS = SS = 0
	xor	bx,	bx
GetFatNumber:
	std					; si --
	lodsw
	and	ax,	ax			; if feof
	clc
	jz	ReadOK				; then return
ReadOneFat:
	dec	ax
	dec	ax
	mov	di,[bp+SectOfCurs-0x7c00]
	and	di,0xff
	mul	di
	add	ax,	[bp-10]
	call	Read_disk
	jnc	GetFatNumber
	stc
ReadOK:
	ret
;======================================================================================
; Get_FileFat	获取文件的FAT链条到堆栈
;				ax = 首指针
;======================================================================================
Get_FileFat:
	pop	di				; DI = IP of the father process
	cld
FileFat_next:
	push	ax				; AX = pointer
	mov	si,	ax			; FAT12:
	add	si,	si			; Next address = pointer * 3 / 2
	add	si,	ax			; SI = AX * 3
	shr	si,	1			; SI / 2
	lodsw
	jnc	bit_check			; if pointer % 2 = 1
	shr	ax,	4			; then clear the low bit
bit_check:					; else
	and	ah,0x0f				; clear the high bit
	cmp	ax,	0xfff			; if pointer table isn't over ?
	jb	FileFat_next			; get next pointer
	xor	ax,	ax			; feof
	push	ax				; save eof
	push	di				; save IP
	ret
;======================================================================================
;find_File	查找文件	ds:si=文件名字偏移地址	正确:cf=0	ax=文件首簇号
;				es:0x0000=根目录缓冲区  错误:cf=1	ax=无意义
;======================================================================================
find_File:
	xor	di,di
	cld
next_Find:
	push	di
	push	si
	mov	cx,	11			; size of file name
	repe	cmpsb
	pop	si
	pop	di
	je	ffind_Down
	add	di,32
	cmp	byte	[es:di],0
	jnz	next_Find
not_found:
	stc
	ret
ffind_Down:
	mov	ax,	[es:di+0x1a]
	clc
	ret
;======================================================================================
;ReadDisk	  读磁盘     ax=绝对扇区号	正确:cf=0	读磁盘时如果超过段
;			     di=要读的扇区数	错误:cf=1	限制将会自动调整段
;			     es:bx=内存位置			并设置bx=0
;--------------------------------------------------------------------------------------
Read_disk:
	push	si
read_next:
	push	ax
	mov	ax,	0x0e2e
	int	0x10
	pop	ax
	push	ax				;ax=绝对扇区号
	xor	dx,	dx
	div     word [ bp+SectOfCly-0x7C00]
						;TEMP = 绝对扇区号 / 每道扇区数
	mov	cx,	  dx			;CL = 绝对扇区号 MOD 每道扇区数 = 未调整的扇区号
	xor	dx,	  dx
	div     word [ bp+DiskHeads-0x7c00]
	mov	ch,	  al			;CL = TEMP /磁头数 = 磁道号
	mov	dh,	  dl			;DH = TEMP MOD 磁头数 = 磁头号
	mov	dl, [bp+NOfDriver-0x7c00]
	inc	cl
	mov	si,	COUNT_Retry
reading_now:
	mov	ax,	ReadOneSector
						;读磁盘
	int	13h
	jnc	read_ok				;读正确,转移
	xor 	ax,	ax
	int 	0x13
	dec     si				;不正确--->继续读,读5次返回错误处理
	jnz	reading_now
	pop	ax
	pop	si
	stc					;设错误标志, CF = 1
	ret					;返回,不再读
read_ok:
	add	bx,	[bp+SectSize-0x7c00]
						;ES:BX=读数据的位置
						;每成功读数据一个扇区,BX+512
						;如果计算的结果超过 0xffff,将回产生进位
	jnc	no_incr_es			;无进位,转移
	mov	ax,	es			;有进位--->ES+1000H
	add	ah,	10h
	mov	es,	ax
no_incr_es:
	pop	ax				;弹出绝对扇区号
	inc	ax				;绝对扇区号加1
	dec	di				;需要读的扇区数减1
	jnz	read_next			;如果没有读完(!=0),继续读下一个扇区
	pop	si				;读完,弹出 si
	clc					;置正确标志
	ret					;返回	
	
;==================================================================================
			BOOTFILENAME
Msg_ErrReadisk	db 0x0d,0x0a,'DISK',0
ERR_KNL		db 0x0d,0x0a,'OSLOADER.SYS',0
ERR_DRV		db 0x0d,0x0a,'FS.DRV',0
Fat12_ERRMSG	db ' : error!',0
Fat12_StartMSG  db 'Loading',0

times Flag_Offset+2-($-$$)	db 0
				dw Flag_BootSect

⌨️ 快捷键说明

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