我有一个基本的引导加载程序,它应该将 FAT12 格式化软盘中的根扇区读取到内存中。(该部分有效)但在实现之后它停止将字符写入屏幕。上次它这样做是因为我忘了弹出一个寄存器。但是我已经三重检查了我是否将每个寄存器都弹出来。
我还使用了 BOCHS 调试器,据此它刚刚到达末尾并执行打印字符命令。
我现在被困住了。如果有人可以看一下我的代码,我会非常高兴。
这是我的代码:
org 0x7c00
bits 16
start: jmp loader
;OEM
TIMES 0Bh-$+start DB 0
bpbBytesPerSector: DW 512
bpbSectorsPerCluster: DB 1
bpbReservedSectors: DW 1
bpbNumberOfFATs: DB 2
bpbRootEntries: DW 224
bpbTotalSectors: DW 2880
bpbMedia: DB 0xF0
bpbSectorsPerFAT: DW 9
bpbSectorsPerTrack: DW 18
bpbHeadsPerCylinder: DW 2
bpbHiddenSectors: DD 0
bpbTotalSectorsBig: DD 0
bsDriveNumber: DB 0
bsUnused: DB 0
bsExtBootSignature: DB 0x29
bsSerialNumber: DD 0xa0a1a2a3
bsVolumeLabel: DB "MOS FLOPPY "
bsFileSystem: DB "FAT12 "
;vars
absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00
;functions
print:
xor bx, bx
lodsb
cmp al, 00h
je print_eof
mov ah, 0eh
int 10h
jmp print
print_eof:
ret
;************************************************;
; Convert LBA to CHS
; AX=>LBA Address to convert
;
; absolute sector = (logical sector / sectors per track) + 1
; absolute head = (logical sector / sectors per track) MOD number of heads
; absolute track = logical sector / (sectors per track * number of heads)
;
;************************************************;
lbachs:
xor dx, dx ; prepare dx:ax for operation
div WORD [bpbSectorsPerTrack] ; calculate
inc dl ; adjust for sector 0
mov BYTE [absoluteSector], dl
xor dx, dx ; prepare dx:ax for operation
div WORD [bpbHeadsPerCylinder] ; calculate
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret
ReadSectors:
push ax ;safety
push bx ;safety
push cx ;safety
call lbachs ;change LBA to CHS (floppy)
mov ah, 0x02 ;function to read sector from floppy
mov al, 0x01 ;read only 1 sector
mov ch, [absoluteTrack] ;at track X
mov cl, [absoluteSector];at sector X
mov dh, [absoluteHead] ;at had X
mov dl, 0x00 ;on drive 00 (floppydrive
int 0x13 ;execute
jnc .succes ;if succeeded goto succes else:
mov ah, 0x00 ;reset floppy drive
mov bl, 0x00 ;drive 0
int 0x13 ;execute
pop cx ;pop
pop bx
pop ax
jmp ReadSectors ;retry
.succes:
pop cx ;pop
pop bx
pop ax
add bx, WORD [bpbBytesPerSector] ;next 512 bytes in memory to write sector to
inc ax ;next sector
LOOP ReadSectors ;and keep looping till cx == 0
ret ;return
;Bootloader
loader:
mov si, msg
call print
xor cx, cx
mov ax, 0x0020 ; 32 byte directory entry
mul WORD [bpbRootEntries] ; number of root entrys
div WORD [bpbBytesPerSector] ; get sectors used by root directory
xchg cx, ax ;;cx=LENGTH in sectors
mov al, [bpbNumberOfFATs] ; Get number of FATs (Useually 2)
mul WORD [bpbSectorsPerFAT] ; number of FATs * sectors per FAT; get number of sectors
add ax, [bpbReservedSectors] ; add reserved sectors
;AX=START as sector in LBA (so needs conversion
mov bx, 0x0200 ; load root directory to 7c00:0x0200
call ReadSectors
mov cx, [bpbRootEntries] ; the number of entrys. If we reach 0, file doesnt exist
mov di, 0x0200 ; Root directory was loaded here
.LOOP:
push cx
mov cx, 11 ; eleven character name
mov si, imageName ; compare the 11 bytes with the name of our file
push di
rep cmpsb ; test for entry match
pop di
je LOAD_FAT ; they match, so begin loading FAT
pop cx
add di, 32 ; they dont match, so go to next entry (32 bytes)
loop .LOOP
jmp FAILURE ; no more entrys left, file doesnt exist :(
LOAD_FAT:
mov bh, 00h ;page to wwrite to.
mov ah, 0eh ;write character
mov al, 'Y' ;write the Y character
int 10h ;execute
jmp EoF ;jump to end of file
FAILURE:
mov bh, 00h ;page to write to
mov ah, 0eh ;write character
mov al, 'N' ;write the N character
int 10h ;execute
EoF:
mov bh, 00h ;see above :P
mov ah, 0eh
mov al, 'D'
int 10h
cli
hlt
streof db 'DONE....',0x0A, 0x0D, 00h
msg db 'Hello!', 0x0D, 0x0A, 00h
msg2 db 'Done reading root directory!', 0x0D, 0x0A, 00h
succ db 'YES file is found!', 00h
fil db 'Failed no file found!', 00h
imageName db "KRNLDR SYS"
times 510 - ($-$$) db 0
dw 0xAA55
提前致谢。
-蒂姆
PS:(对于那些会说我不应该复制代码的人)我只从breakthorn复制了“检查文件是否存在”代码,以查看我是否正确加载了ROOT。