创建辅助函数就是为了这张流程图
C语言和汇编同一个功能的代码对比:
首先看看cx是不是为0,如果为0就跳转到equal(相等)处,不为0那么将si处的数据放入al,如果与di处一样,那么就跳转到goon继续比较,si++指向下一个单元,di++,cx–,跳转到compare继续比较(while循环)
org 0x7c00
jmp short start
nop
define:
BaseOfStack equ 0x7c00
RootEntryOffset equ 19
RootEntryLength equ 14
header:
BS_OEMName db "D.T.Soft"
BPB_BytsPerSec dw 512
BPB_SecPerClus db 1
BPB_RsvdSecCnt dw 1
BPB_NumFATs db 2
BPB_RootEntCnt dw 224
BPB_TotSec16 dw 2880
BPB_Media db 0xF0
BPB_FATSz16 dw 9
BPB_SecPerTrk dw 18
BPB_NumHeads dw 2
BPB_HiddSec dd 0
BPB_TotSec32 dd 0
BS_DrvNum db 0
BS_Reserved1 db 0
BS_BootSig db 0x29
BS_VolID dd 0
BS_VolLab db "D.T.OS-0.01"
BS_FileSysType db "FAT12 "
start:
mov ax, cs
mov ss, ax
mov ds, ax
mov es, ax
mov sp, BaseOfStack
mov ax, RootEntryOffset
mov cx, RootEntryLength
mov bx, Buf
call ReadSector
mov si, Target
mov cx, TarLen
mov dx, 0
call FindEntry
cmp dx, 0
jz output
jmp last//目标查找到后跳转到last后CPU停止工作
output:
mov bp, MsgStr
mov cx, MsgLen
call Print
last:
hlt
jmp last
; es:bx --> root entry offset address
; ds:si --> target string
; cx --> target length
;
; return:
; (dx != 0) ? exist : noexist
; exist --> bx is the target entry
FindEntry:
push di
push bp
push cx
mov dx, [BPB_RootEntCnt]//最多几个项
mov bp, sp
find:
cmp dx, 0
jz noexist
mov di, bx
mov cx, [bp]
call MemCmp
cmp cx, 0
jz exist
add bx, 32//每一项占32字节
dec dx //dx-1
jmp find
exist:
noexist:
pop cx
pop bp
pop di
ret
; ds:si --> source
; es:di --> destination
; cx --> length
;
; return:
; (cx == 0) ? equal : noequal
MemCmp:
push si//防止寄存器的值因为函数的调用被改变所以先放入栈中,后面再出栈
push di
push ax
compare:
cmp cx, 0
jz equal//如果为0说明相等,跳转到equal
mov al, [si]//先si指向的内存的一个字节拿出来放入al中
cmp al, byte [di]//与di指向的一个字节比较,相等就goon
jz goon
jmp noequal
goon:
inc si
inc di
dec cx
jmp compare//等价于C语言的while循环
equal:
noequal:
pop ax
pop di
pop si
ret
; es:bp --> string address
; cx --> string length
Print:
mov ax, 0x1301
mov bx, 0x0007
int 0x10
ret
; no parameter
ResetFloppy:
push ax
push dx
mov ah, 0x00
mov dl, [BS_DrvNum]
int 0x13
pop dx
pop ax
ret
; ax --> logic sector number
; cx --> number of sector
; es:bx --> target address
ReadSector:
push bx
push cx
push dx
push ax
call ResetFloppy
push bx
push cx
mov bl, [BPB_SecPerTrk]
div bl
mov cl, ah
add cl, 1
mov ch, al
shr ch, 1
mov dh, al
and dh, 1
mov dl, [BS_DrvNum]
pop ax
pop bx
mov ah, 0x02
read:
int 0x13
jc read
pop ax
pop dx
pop cx
pop bx
ret
MsgStr db "No LOADER ..."
MsgLen equ ($-MsgStr)
Target db "LOADER "
TarLen equ ($-Target)
Buf:
times 510-($-$$) db 0x00
db 0x55, 0xaa