突破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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值