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

📄 bootsec.asm

📁 ucos在x86上的移植代码。吐血推荐啊
💻 ASM
字号:
; bootsec.asm :;     启动扇区引导代码, 采用nasm编译生成bootsec.bin, 使用WinImage等工具写入软盘; 镜像文件的起始512字节.; ; Copyright(C) 2007, Alex P.Wonder; phoenixwonder@gmail.com;%include "bootsec.inc"	org 07c00h		  jmp short _start  nop;==========================================;	FAT12引导扇信息(BS+BPB表);==========================================	DECLARE_BOOTSEC_INFO;==========================================;	全局变量;==========================================LoaderFileName 			db 'LOADER  BIN'  ; windows98格式化, xxxxxxxxyyy, x中字符不够用空格0x20补齐loadingmsg					db 10,'Loading...'errmsg							db 14,'Loaded failed!'wSectorNo						dw 0wRootDirSizeForLoop dw 0bOdd 								db 0;==========================================;	引导代码;==========================================_start:	;初始化段寄存器	mov ax, cs	mov ds, ax	mov ss, ax	mov es, ax	mov sp, BaseOfBoStack	mov ax, 0xb800	mov gs, ax  ;软驱复位	xor ah, ah	xor dl, dl	int 13h		; --在软盘根目录中查找系统引导程序文件'loader.bin'--	mov word [wSectorNo], SectorNoOfRootDir	mov ax, [BPB_RootEntCnt] ; 根目录总数 -> wRootDirSizeForLoop(查找总次数赋初值)	mov word [wRootDirSizeForLoop], ax	L_SEARCH_ROOT_DIR_HERE:	mov ax, BaseOfLoader	mov es, ax	; (es) <- BaseOfLoader	mov bx, 0   ; es:bx -> BaseOfLoader: 0	mov ax, [wSectorNo]  ; 读一个扇区FAT表内容到内存es:bx	mov cl, 1	call ReadSector	push es	mov  ax, ds	mov  es, ax	push bp	mov bp, loadingmsg	mov dx, 0x0000	call ShowBootMsg	pop bp	pop es		mov si, LoaderFileName		; ds:si -> 'LOADER.BIN'	mov di, 0	cld	mov dx, 10h  ; 512 / 32(一个FAT项占用的字节数) = 16(一个扇区存有16个FAT项)L_SEARCH_FOR_LOADERBIN:	cmp dx, 0	jz  L_GOTO_NEXT_SECTOR ; 如果当前扇区中没找到,则查找下一个FAT扇区	dec dx	mov cx, 11 ;8.3 fat12 filename formatL_CMP_FILENAME:              ;	cmp cx, 0                  ;	jz  L_FILENAME_FOUND       ;	dec cx                     ;	lodsb		; ds:si -> al, si++	cmp al, byte [es:di]       ;	jz	L_GO_ON                ; 当前字符相同则继续比较文件名的下一个字符;	jmp L_DIFFERENT            ; 否则,取下一个FAT目录项比较L_GO_ON:                     ;	inc di                     ;	jmp L_CMP_FILENAME         ;L_DIFFERENT:	and di, 0ffe0h             ; di & 0xffe0 = 当前比较目录项的首字节地址	add di, 20h                ; 跳过32字节,即取下一个目录项的首字节地址	mov si, LoaderFileName     ; LoaderFileName首字节地址 -> (si)	dec word [wRootDirSizeForLoop] ;wRootDirSizeForLoop--, 总比较次数-1	cmp word [wRootDirSizeForLoop], 0	jz  L_NO_LOADERBIN	;总次数为0时还没有找到,放弃查找	jmp L_SEARCH_FOR_LOADERBINL_GOTO_NEXT_SECTOR:	inc word [wSectorNo] ; wSectorNo++, 下一个FAT扇区		jmp L_SEARCH_ROOT_DIR_HEREL_NO_LOADERBIN:	call KillMotor ;关闭驱动器马达	;显示启动错误信息	mov bp, errmsg	mov dx, 0x0200	call ShowBootMsg			hlt ; 系统启动失败了 :(L_FILENAME_FOUND: ;找到了LOADER.BIN	  mov		ax, RootDirSectors  and		di, 0xffe0  ;这时候的di还是指向根目录区中对应的目录项(LOADER.BIN)  add		di, 01ah		;找到首Sector, 01ah偏移位置存放了该文件在数据区中的首簇号  mov   cx, word [es:di]  push  cx  ; 保存首簇号, 1)  add 	cx, ax	;  (cx) <= RootDirSectors + 首簇号    add		cx, DeltaSectorNo ; 数据区的第一个簇号是2,不是0或1, 所以DeltaSectorNo=1 + 9*2 - 2=17                          ; 执行此指令后, (cx) = loader.bin的第一个逻辑扇区号                            mov 	ax, BaseOfLoader  mov 	es, ax  mov 	bx, 0  mov 	ax, cx ;逻辑扇区号=>(ax)L_GOON_LOADING_FILE: 	mov 	cl, 1 ;读一个扇区到 es:bx 	call	ReadSector 	pop		ax			; 当前簇号 => (ax) 	call  GetFATEntry ;获得下一个簇号,并保存在ax中 	cmp		ax, 0ff8h 	jae		L_FILE_LOADED ;文件读取结束 	push  ax ;保存当前簇号 	 	; 下面几行代码获得当前簇号对应的逻辑扇区号 	mov 	dx, RootDirSectors 	add		ax, dx 	add		ax, DeltaSectorNo 	add		bx, [BPB_BytsPerSec] ;指向下一个存放文件内容的内存地址 	jmp		L_GOON_LOADING_FILEL_FILE_LOADED:	;loader加载完毕, 执行loader	jmp BaseOfLoader:0;================================================;    				定义一些函数;================================================;读取一个扇区;  ax - 起始逻辑扇区号;  cl - 扇区数;  es:bx - 返回地址ReadSector:	push 	bp	mov		bp, sp		sub		sp, 2   ;开辟两个字节存放需要读取的扇区数	mov   byte [bp - 2], cl		push	bx	mov		bl, [BPB_SecsPerTrk]	div   bl			; y在al中(商), z在ah中(余数)	inc		ah			; z++(扇区号)	mov		cl, ah  ; cl <- 起始扇区号	mov		dh, al  ; dh <- y	shr   al, 1   ; 柱面号	mov		ch, al	and 	dh, 1 ; 磁头号	pop		bx		mov		dl, 0;[BS_DrvNum].CoOnReading:	mov ah, 2	mov al, byte [bp - 2]	int	13h	jc	.CoOnReading	; 如果读取错误,CF=1, 这里就不停地读,直到正确为止		mov ax, 0xb800	mov gs, ax	inc byte [gs:(80*6 + 0)*2]	add sp, 2	pop bp	ret; 功  能:;   根据文件的簇号获得对应FAT表项内容(文件下一个簇号).; 输  入:; 	ax - 文件的当前簇号; 输  出:;		ax - 下一个簇号; 返回值:GetFATEntry:	push es	push bx		push ax		mov ax, BaseOfLoader	sub ax, 0100h	mov es, ax     ;BaseOfLoader地址前空出4k给es段(用来临时保存读取的FAT扇区)		pop ax		mov byte [bOdd], 0	mov bx, 3	mul bx    ; ax*3 => (dx:ax)	mov bx, 2	div bx    ; (dx:ax) / 2 => (ax):商, (dx):余数	cmp dx, 0	jz  L_EVEN	mov byte [bOdd], 1L_EVEN:	xor 	dx, dx	mov 	bx, [BPB_BytsPerSec]	div 	bx ; 求逻辑扇区号对应的FAT项在第几个FAT内容扇区中, (ax)/BPB_BytsPerSec => ax(扇区号)	push 	dx ; dx保存FAT项在扇区中的偏移	mov  	bx, 0	; 连续读取2个逻辑扇区号对应的FAT表扇区到内存地址es:bx	add  	ax, SectorNoOfFAT1	mov  	cl, 2	call 	ReadSector	pop  	dx	add  	bx, dx 			;(es:bx + dx) 保存文件的FAT12项	mov  	ax, [es:bx] ;读2个字节到ax	cmp  	byte [bOdd], 1	jnz  	L_EVEN_2	shr  	ax, 4L_EVEN_2:	and  ax, 0fffhL_GET_FAT_ENTRY_OK:	pop bx	pop es	ret; 功  能:;     显示引导扇信息; 输  入:;		dh, dl -- y, x;   es, bp -- addr of str; 输  出:;   (无)ShowBootMsg	push 	ax	push 	bx	push 	cx		xor 	cx, cx	mov	 	cl, [bp] 	;获得字符串字符个数	inc 	bp 				;指向字符串中第一个字符			mov 	ah, 19	mov 	bh, 0 		;页号	mov 	bl, 0x0f  ;白色字体,黑色背景	mov 	al, 1 		;光标移动到最后一个字符后面	int 	10h	dec bp ;恢复bp的值	pop 	cx	pop 	bx	pop 	ax	ret;; 关闭软盘驱动器马达;KillMotor:	push  ax		push 	dx		mov		dx, 03f2h	mov 	al, 0	out		dx, al		pop		dx	pop   ax	ret	;补齐512字节	times (510 - $ + $$) db 0  dw 0xaa55

⌨️ 快捷键说明

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