7.突破512字节的限制(中)

Posted 阿弥陀佛.a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7.突破512字节的限制(中)相关的知识,希望对你有一定的参考价值。



创建辅助函数就是为了这张流程图





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

以上是关于7.突破512字节的限制(中)的主要内容,如果未能解决你的问题,请参考以下文章

6.突破512字节的限制(上)

操作系统--突破512字节的限制

第七课 突破512字节限制--中

第六课 突破512字节的限制 上

第八课 突破512字节的限制--下

8.突破512字节的限制(下)