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

📄 boot.asm

📁 jserv写的orz小内核 有详细的注释
💻 ASM
字号:
; Boot sector for floppy disk (720k/1.44M, FAT12)
;

%define KERNEL_START_SEG	 0x2000

[BITS 16]
[ORG 0x7C00]

Base:
	jmp short Begin
	nop

oem             db 'OrzMicro' 		; OEM ID
bytesPerSector  dw 0x0200		; Bytes per sector 512
sectPerCluster  db 0x02			; Sectors per cluster
resSectors      dw 0x01			; Reserved sectors at beginning
fatCopies       db 0x02			; Fat copies
rootEntCnt      dw 0x0070		; Root directory entries
totalSectors    dw 0x05A0		; Total sectors on disk
media           db 0xF9			; Media descriptor byte
sectPerFat      dw 0x0003		; Sectors per FAT
sectPerTrack    dw 0x0009		; Sectors per track
heads           dw 0x0002		; Heads
hiddenSectors   dd 0			; Special hidden sectors
sectorHuge      dd 0
drive           db 0			; Physical drive number
		db 0
extendedBPB     db 0x29			; Extended boot record signature
volumeID        dd 0			; Volume serial number
volumeLabel     db 'Orz Disk   '	; Volume label
fileSys         db 'FAT12   '		; File system ID

;------------------------------------------------------------------------

Begin:
	cli			     ; 屏蔽所有外部中断,中断标志置0
	cld              ; 方向标志置1指令,字符处理由低位往高位
	mov ax,cs		 ; jiao: actually, cs = 0 and eip = 0x7c00
	mov ds,ax
	mov ss,ax
	mov sp,7c00h
	sti               ; 中断标志置1指令,允许中断

	mov [curDrive],dl   	; fred:從 BIOS 取得目前使用的裝置

;-----------------------------------------------
; 初始化顯示記憶體並顯示核心訊息    
; 函式 Print 的參數:SI = 字串, ES:DI = 显存位置, AH = 顏色

 	mov ax,$03		;為中斷設定 AH=03h 以讀取游標位置
	int $10           ;開始中斷 10h,用来读取光标位置

	mov ax,$0B800             ;设定显存地址:0xB8000
	mov es,ax                 ;设定ES区段
	xor di,di                 ;设定DI:由第零列第零行开始写入
	;在屏幕上显示核心讯息

	mov si,fname           ;设定SI:字符串为核心档案名称
	mov ah,$2F             ;设定AH:字串颜色为白色
	call Print             ;呼叫显示字串函数

;-----------------------------------------------
; Get Drive Params

;-----------------------------------------------


		mov si,[hiddenSectors]
		mov di,[hiddenSectors+2]
		add si,[resSectors]
		adc di,0		; DI:SI = first FAT sector
		mov [fatStart],si
		mov [fatStart+2],di

		mov al,[fatCopies]
		xor ah,ah
		mul WORD [sectPerFat]	; DX:AX = total sectors in FATs
		add si,ax
		adc di,dx		; DI:SI = first ROOT sector
                              ;adc就是add再加上进位位cf的值
		mov [rootStart],si
		mov [rootStart+2],di

		mov ax,[rootEntCnt]
		mov cl,5		; TODO: reminding yet?
		shl ax,5
		xor dx,dx
		div WORD [bytesPerSector];
		mov [secPerRoot],ax

		add si,ax
		adc di,0		; DI:SI = first data sector
		mov [dataStart],si
		mov [dataStart+2],di

;-----------------------------------------------
; Find File
;-----------------------------------------------

		mov ax,$1000
		mov es,ax
		mov ax,[rootStart]
		mov dx,[rootStart+2]
		mov cx,[secPerRoot]
		xor bx,bx
		call ReadSectors

		xor di,di		; ES:DI, DS:SI

FindFile0:	mov cx,11
		mov si,fname
		push di
		repe cmpsb
		pop di
		mov ax,[es:di+$1A]	; cluster number
		jz FindFile1

		add di,$20		; next dir entry
		cmp BYTE [es:di],0	; this is end of root?
		jnz FindFile0

		jmp PrintError

FindFile1:

;-----------------------------------------------
; Get FAT Chain
;-----------------------------------------------

		push ax			; jiao: cover root
		mov ax,$1000
		mov es,ax
		xor bx,bx
		mov cx,[sectPerFat]
		mov ax,[fatStart]
		mov dx,[fatStart+2]
		call ReadSectors
		pop ax

		push ds		;
		push es		; swap (DS, ES)
		pop ds		;
		pop es		;
		mov di,fatBuf

GetFatChain0:	stosw		; WORD [ES:DI] = AX, DI += (DF==0)?(2):(-2)

		; use following code only for FAT12
		mov si,ax
		add si,si
		add si,ax
		shr si,1	; SI = (AX * 3) / 2, (-*-)
		lodsw		; AX = WORD [DS:SI], SI += (DF==0)?(2):(-2)
		jnc GetFatChain1	; (-*-)
		mov cl,4
		shr ax,cl
GetFatChain1:	and ah,$0F

		cmp ax,$0FF8	; This is EOC? (>= 0x0FF8)
		jc GetFatChain0

		xor ax,ax
		stosw

		push cs		; Restore DS
		pop ds

;-----------------------------------------------
; Load File
;-----------------------------------------------

		mov ax,KERNEL_START_SEG
		mov es,ax
		xor bx,bx
		mov si,fatBuf

LoadFile0:	lodsw		; AX = WORD [DS:SI], SI += (DF==0)?(2):(-2)
		and ax,ax
		jz RunemAll

		dec ax
		dec ax		; clusters numbers start from 2

		mov cl,[sectPerCluster]
		xor ch,ch
		mul cx
		add ax,[dataStart]
		adc dx,[dataStart+2]
		call ReadSectors

		push es
		mov ax,$0B800
		mov es,ax
		mov di,160
ll0:   		mov WORD [es:di], $072E
    		inc di
    		inc di
    		mov [cs:ll0-2], di
		pop es

		jmp short LoadFile0

;-----------------------------------------------

RunemAll:	mov ax,$0B800
		mov es,ax
		mov di,320
		mov si,msg_ok
		mov ah,14
		call Print

		mov dl,[drive]
		mov ax,KERNEL_START_SEG
		mov ds,ax
		mov es,ax
		jmp WORD KERNEL_START_SEG:0000

;------------------------------------------------------------------------

PrintError:    	mov si,err_notfound
		mov ax,$0B800		; jiao: start of color text video buffer
		mov es,ax
		mov di,160		; jiao: the second line, 80X25
		mov ah,$4C
		call Print

PrintError1:	jmp short PrintError1

;------------------------------------------------------------------------

; SI = szText, ES:DI = screen_address, AH = color
Print:		mov al,[cs:si]		; jiao: display by using color text video buffer
		and al,al
		jz Print0
		mov [es:di],al
		inc di
		mov [es:di],ah
		inc di
		inc si
		jmp short Print
Print0:		ret

;------------------------------------------------------------------------

; DX:AX = first_sector_LBA, ES:BX = buffer, CX = numRead
ReadSectors:	push ax
		push dx
		push cx

		push es
		push bx
		call ReadSector
		pop bx
		pop es

		add bx,[bytesPerSector]
		jnc ReadSectors1
		mov ax,es
		add ah,$10
		mov es,ax

ReadSectors1:	pop cx
		pop dx
		pop ax

		add ax,1
		adc dx,0
		loop ReadSectors
		ret

; DX:AX = sector_LBA, ES:BX = buffer
ReadSector:	div WORD [sectPerTrack]
		inc dl			; sector = 1 + sector_LBA % sectPerTrack
		mov cl, dl     		; CL = sector

		xor dx,dx
		div WORD [heads]	; head = (sector_LBA/sectPerTrack) % heads
		mov dh,dl		; DH = head

		mov ch,al		; cyl = (sector_LBA/sectPerTrack) / heads, CH = cyl
		mov dl,[curDrive]	; DL = drive

		mov ax,$0201
		int $13
		jc PrintError
		ret

;------------------------------------------------------------------------

		;   12345678ext
fname		db "ORZKERNL   ",0
err_notfound	db "Err",0
msg_ok		db "OK",0

;------------------------------------------------------------------------
EndOfBase:
		times (0x01FE-(EndOfBase-Base)) db 0
		dw 0xAA55

curDrive  	equ $		; db 0	; jiao: constant, not occupy space, their addresses are right after 0x7c00+512
fatStart	equ $+1		; dd 0
rootStart	equ $+5		; dd 0
secPerRoot	equ $+9		; dw 0
dataStart	equ $+11	; dd 0

fatBuf		equ $+15

⌨️ 快捷键说明

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