主引导程序控制权的转移

目前内存使用情况:
在这里插入图片描述
将控制权从boot转移到Loader
Fat Table占据4KB空间,起始于0x7e00

在这里插入图片描述
在这里插入图片描述
boot.asm:

org 0x7c00

jmp short start
nop

define:
    BaseOfStack      equ 0x7c00
    BaseOfLoader     equ 0x9000
    RootEntryOffset  equ 19
    RootEntryLength  equ 14
    EntryItemLength  equ 32
    FatEntryOffset   equ 1
    FatEntryLength   equ 9

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
	
	mov si, bx
	mov di, EntryItem
	mov cx, EntryItemLength
	
	call MemCpy
	
	mov ax, FatEntryLength
	mov cx, [BPB_BytsPerSec]
	mul cx
	mov bx, BaseOfLoader
	sub bx, ax
	
	mov ax, FatEntryOffset
	mov cx, FatEntryLength
	
	call ReadSector
	
	mov dx, [EntryItem + 0x1A]
	mov si, BaseOfLoader
	
loading:
    mov ax, dx
    add ax, 31
    mov cx, 1
    push dx
    push bx
    mov bx, si
    call ReadSector
    pop bx
    pop cx
    call FatVec
    cmp dx, 0xFF7
    jnb BaseOfLoader
    add si, 512
    jmp loading
	
output:	
    mov bp, MsgStr
    mov cx, MsgLen
	call Print
	
last:
    hlt
	jmp last	


; cx --> index
; bx --> fat table address
;
; return:
;     dx --> fat[index]
FatVec:
    mov ax, cx
    mov cl, 2
    div cl
    
    push ax
    
    mov ah, 0
    mov cx, 3
    mul cx
    mov cx, ax
    
    pop ax
    
    cmp ah, 0
    jz even
    jmp odd

even:    ; FatVec[j] = ( (Fat[i+1] & 0x0F) << 8 ) | Fat[i];
    mov dx, cx
    add dx, 1
    add dx, bx
    mov bp, dx
    mov dl, byte [bp]
    and dl, 0x0F
    shl dx, 8
    add cx, bx
    mov bp, cx
    or  dl, byte [bp]
    jmp return
    
odd:     ; FatVec[j+1] = (Fat[i+2] << 4) | ( (Fat[i+1] >> 4) & 0x0F );
    mov dx, cx
    add dx, 2
    add dx, bx
    mov bp, dx
    mov dl, byte [bp]
    mov dh, 0
    shl dx, 4
    add cx, 1
    add cx, bx
    mov bp, cx
    mov cl, byte [bp]
    shr cl, 4
    and cl, 0x0F
    mov ch, 0
    or  dx, cx

return: 
    ret

; ds:si --> source
; es:di --> destination
; cx    --> length
MemCpy:
    
    cmp si, di
    
    ja btoe
    
    add si, cx
    add di, cx
    dec si
    dec di
    
    jmp etob
    
btoe:
    cmp cx, 0
    jz done
    mov al, [si]
    mov byte [di], al
    inc si
    inc di
    dec cx
    jmp btoe
    
etob: 
    cmp cx, 0
    jz done
    mov al, [si]
    mov byte [di], al
    dec si
    dec di
    dec cx
    jmp etob

done:   
    ret

; 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 cx
    
    mov dx, [BPB_RootEntCnt]
    mov bp, sp
    
find:
    cmp dx, 0
    jz noexist
    mov di, bx
    mov cx, [bp]
    push si
    call MemCmp
    pop si
    cmp cx, 0
    jz exist
    add bx, 32
    dec dx
    jmp find

exist:
noexist: 
    pop cx
       
    ret

; ds:si --> source
; es:di --> destination
; cx    --> length
;
; return:
;        (cx == 0) ? equal : noequal
MemCmp:

compare:
    cmp cx, 0
    jz equal
    mov al, [si]
    cmp al, byte [di]
    jz goon
    jmp noequal
goon:
    inc si
    inc di
    dec cx
    jmp compare
    
equal: 
noequal:   

    ret

; es:bp --> string address
; cx    --> string length
Print:
    mov dx, 0
    mov ax, 0x1301
	mov bx, 0x0007
	int 0x10
    ret

; no parameter
ResetFloppy:
    
    mov ah, 0x00
    mov dl, [BS_DrvNum]
    int 0x13
    
    ret

; ax    --> logic sector number
; cx    --> number of sector
; es:bx --> target address
ReadSector:
    
    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
    
    ret

MsgStr db  "No LOADER ..."	
MsgLen equ ($-MsgStr)
Target db  "LOADER     "
TarLen equ ($-Target)
EntryItem times EntryItemLength db 0x00
Buf:
	
	times 510-($-$$) db 0x00
	
	db 0x55, 0xaa

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

loader.asm:

org 0x9000

begin:
    mov si, msg

print:
    mov al, [si]
    add si, 1
    cmp al, 0x00//相等的话跳转到结束的地方
    je end
    mov ah, 0x0E//不相等的话就打印
    mov bx, 0x0F
    int 0x10
    jmp print

end:
    hlt
    jmp end
    
msg:
    db 0x0a, 0x0a//换行
    db "Hello, D.T.OS!"
    db 0x0a, 0x0a
    db 0x00

接下来将load拷贝到虚拟软盘中去:
先将虚拟软盘挂载到Linux去,在拷贝进去:
在这里插入图片描述
结果:
在这里插入图片描述

makefile:

.PHONY : all clean rebuild

BOOT_SRC := boot.asm
BOOT_OUT := boot

LOADER_SRC := loader.asm
LOADER_OUT := loader

IMG := data.img
IMG_PATH := /mnt/hgfs

RM := rm -fr

all : $(IMG) $(BOOT_OUT) $(LOADER_OUT)
	@echo "Build Success ==> D.T.OS!"

$(IMG) :
	bximage $@ -q -fd -size=1.44
	
$(BOOT_OUT) : $(BOOT_SRC)
	nasm $^ -o $@
	dd if=$@ of=$(IMG) bs=512 count=1 conv=notrunc
	
$(LOADER_OUT) : $(LOADER_SRC)
	nasm $^ -o $@
	sudo mount -o loop $(IMG) $(IMG_PATH)
	sudo cp $@ $(IMG_PATH)/$@
	sudo umount $(IMG_PATH)
	
clean :
	$(RM) $(IMG) $(BOOT_OUT) $(LOADER_OUT)
	
rebuild :
	@$(MAKE) clean
	@$(MAKE) all

小结

  1. Boot需要进行重构保证在512字节内完成功能
  2. 在汇编程序中尽量确保函数调用前后通用寄存器的状态不变
  3. Boot成功加载Loader后将控制权转移
  4. Loader程序没有代码体积上的限制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值