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

Posted 阿弥陀佛.a

tags:

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



ax bx的值是规定好的,不必深究



编写如下makefile:

.PHONY : all clean rebuild

SRC := boot.asm//主引导程序

OUT := boot.bin//主引导程序编译得到的二进制代码

IMG := data.img//虚拟软盘文件

RM := rm -fr

all : $(OUT) $(IMG)
	dd if=$(OUT) of=$(IMG) bs=512 count=1 conv=notrunc//将二进制代码写入虚拟软盘0扇区
	@echo "Success!"

$(IMG) :
	bximage $@ -q -fd -size=1.44//创建虚拟软盘文件

$(OUT) : $(SRC)
	nasm $^ -o $@

clean :
	$(RM) $(IMG) $(OUT)

rebuild :
	@$(MAKE) clean
	@$(MAKE) all


以上是简单的打印字符串代码,应该打印“Hello,”
make:

先编译生成二进制文件,将二进制代码写入软盘

将这个软盘作为启动盘
结果打印了:

因为没有清屏操作,所以之前的东西没有清除
接下来创建打印函数:


栈起始地址定义在0x7c00处,栈的增长方向是高地址向低地址处增长,所以函数调用时的压栈操作不会影响0x7c00高地址处的汇编代码


上述程序会打印“Hello,DTOS!”

接下来:



也就是1.44MB




重置软驱函数:

为什么要将这两个寄存器先入栈再出栈,说是因为要先备份?

源码:

org 0x7c00

//short代表短跳转,jmp1个字节 目标地址也占1个字节,nop空指令也是1个字节
jmp short start//跳转指令,跳转3个字节,为什么?参考之前的FAT12文件系统主引导去内容
nop

define:
    BaseOfStack equ 0x7c00//栈空间基地址

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, 34
    mov cx, 1
    mov bx, Buf
    
    call ReadSector
    
    mov bp, Buf
    mov cx, 29
    
    call Print
    
last:
    hlt
    jmp last    

; 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//余数放入cl寄存器
    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  "Hello, DTOS!"    
MsgLen equ ($-MsgStr)//$:当前地址,MsgStr:字符串起始地址,相减就是长度
Buf:
    times 510-($-$$) db 0x00
    db 0x55, 0xaa


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

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

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

第7课 - 突破512字节的限制(中)

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

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

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