《自己动手写操作系统》,boot部分搞定,特来上码,是NASM不是MASM,注意编译器
%define buffseg 09000horg 07c00h
jmp short LABEL_START ; Start to boot.
nop ; 这个 nop 不可少
; 下面是 FAT12 磁盘的头
BS_OEMName DB 'ForrestY' ; OEM String, 必须 8 个字节
BPB_BytsPerSec DW 512 ; 每扇区字节数
BPB_SecPerClus DB 1 ; 每簇多少扇区
BPB_RsvdSecCnt DW 1 ; Boot 记录占用多少扇区
BPB_NumFATs DB 2 ; 共有多少 FAT 表
BPB_RootEntCnt DW 224 ; 根目录文件数最大值
BPB_TotSec16 DW 2880 ; 逻辑扇区总数
BPB_Media DB 0xF0 ; 媒体描述符
BPB_FATSz16 DW 9 ; 每FAT扇区数
BPB_SecPerTrk DW 18 ; 每磁道扇区数
BPB_NumHeads DW 2 ; 磁头数(面数)
BPB_HiddSec DD 0 ; 隐藏扇区数
BPB_TotSec32 DD 0 ; 如果 wTotalSectorCount 是 0 由这个值记录扇区数
BS_DrvNum DB 0 ; 中断 13 的驱动器号
BS_Reserved1 DB 0 ; 未使用
BS_BootSig DB 29h ; 扩展引导标记 (29h)
BS_VolID DD 0 ; 卷序列号
BS_VolLab DB 'Tinix0.01 '; 卷标, 必须 11 个字节
BS_FileSysType DB 'FAT12 ' ; 文件系统类型, 必须 8
LABEL_START:
mov ax,cs
mov ds,ax
mov ss,ax
mov sp,0100h
mov bp,0100h
zzz:
xor bx,bx
call readdisk
xor di,di
inc word[rootdirsector]
cmp word[rootdirsector],33
jae nofind
ad:
mov si,LoaderFileName
mov cx,11
repe cmpsb
jcxz find
and di,0ffe0h
add di,20h
inc byte[num]
cmp byte[num],13
je zzz
jmp ad
jmp $
readdisk:
mov ah,0
mov dl,0
int 13h
push bx
mov ax,[rootdirsector]
mov bl,18
div bl
inc ah
mov cl,ah
mov dh,al
shr al,1
mov ch,al
and dh,1
mov dl,0
mov ax,buffseg
mov es,ax
pop bx
xx:
mov ah,02h
mov al,byte[sectornum]
int 13h
jc xx
ret
find:
add di,0fh
mov ax,[es:di]
push ax
xor bx,bx
mov byte[sectornum],2
mov word[rootdirsector],1
call readdisk
mov bx,0400h
pop ax
readnext:
push bx
push ax
mov word[rootdirsector],ax
add word[rootdirsector],31
mov word[sectornum],1
call readdisk
pop ax
mov bx,12
mul bx
mov bx,8
div bx
mov bx,ax
mov ax,[es:bx]
cmp dx,0
je oushu
shr ax,4
jmp xa
oushu:
and ax,0fffh
xa:
cmp ax,0ff8h
jae jieshu
cmp ax,0ff7h
je huaipan
pop bx
add bx,0200h
jmp readnext
jieshu:
jmp 09000h:0400h
huaipan:
jmp $
nofind:
push nofindmessage
push nofindstrlen
mov dh,0
mov ax,cs
mov es,ax
call dispstr
add sp,4
jmp $
dispstr:
mov ax, [bp-2]
mov cx, [bp-4]
push bp
mov bp, ax ; ES:BP = 串地 ; CX = 串长度
mov ax, 01301h ; AH = 13, AL = 01h
mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
mov dl, 0
int 10h
pop bp ; int 10h
ret
buffoffset dw 0400h
sectornum db 1
num db 0
rootdirsector dw 19
findmessage db "find...."
findstrlen equ $-findmessage
nofindmessage db "find fail..."
nofindstrlen equ $-nofindmessage
LoaderFileName db "LOADER BIN"
strlen equ $-LoaderFileName
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志