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字节的限制(上)的主要内容,如果未能解决你的问题,请参考以下文章