当前位置:   article > 正文

在主引导程序中打印字符串,读取软盘数据_可引导asm程序读取软盘

可引导asm程序读取软盘

随记:
1 在汇编中可以定义函数,函数名使用标签定义, 函数体最后一条指令是 ret, 调用函数 是call function

2 如果代码中定义了函数,那么需要定义栈空间。用于保存关键寄存器的值,栈顶地址通过sp寄存器保存

3 汇编中用 equ 定义常量,如 Const equ 0x7c00 == #define Const 0x7c00 .

4 dx(db,dw,dd) 可以定义变量 他们与 equ的差别在于,equ定义不会占用内存空间,而dx定义占用对应的内存空间

db定义字节类型变量,一个字节数据占1个字节单元,读完一个,偏移量加1

dw定义字类型变量,一个字数据占2个字节单元,读完一个,偏移量加2

dd定义双字类型变量,一个双字数据占4个字节单元,读完一个,偏移量加4
  • 1
  • 2
  • 3
  • 4
  • 5

5 and 按位与 运算

6 汇编中的16位除法操作(div)
在这里插入图片描述

一 在主引导程序中打印字符串 – 直接调用系统服务
在这里插入图片描述

二 主引导程序中读取指定扇区数据 – 直接调用系统服务

在这里插入图片描述

不过参数比较麻烦,这涉及到软盘的基本信息:

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

在这里插入图片描述

在这里插入图片描述

makefile

.PHONY : all clean rebuild

SRC := boot.asm
OUT := boot.bin
IMG := data.img

RM := rm -fr

#将主引导程序的二进制程序 烧写到 虚拟软盘的第0个扇区
all : $(OUT) $(IMG)
	dd if=$(OUT) of=$(IMG) bs=512 count=1 conv=notrunc
	@echo "Success!"

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

#编译主引导程序代码 成二进制程序
$(OUT) : $(SRC)
	nasm $^ -o $@

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

rebuild :
	@$(MAKE) clean
	@$(MAKE) all
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

bochsrc 配置

###############################################################
# Configuration file for Bochs
###############################################################

# how much memory the emulated machine will have
megs: 32

# filename of ROM images
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin

# what disk images will be used
floppya: 1_44=data.img, status=inserted

# choose the boot disk.
boot: a

# where do we send log messages?
# log: bochsout.txt

# disable the mouse
mouse: enabled=0

# enable key mapping, using US layout as default.
keyboard_mapping: enabled=1, map=/usr/local/share/bochs/keymaps/x11-pc-us.map
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

boot.asm

;主引导程序起始地址
org 0x7c00

;主引导程序的前三个字节 是跳转指令
;跳转指令(jmp指令占 一个字节) 跳到start标签(目标地址标签 是短跳转 占一个字节) nop(空指令占一个字节)
;这样写的原因是 下面的定义的 FAT12文件头并不是可执行的代码,所以需要跳过这一段信息 到 start 标签执行
jmp short start
nop

;栈空间起始地址
define:
    BaseOfStack equ 0x7c00
	
	
; FAT12文件系统所需要的头
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
	;指定 sp栈顶指针寄存器 值
    mov sp, BaseOfStack
    
	;指定参数 逻辑扇区号:34
    mov ax, 34
	;需要连续读取一个扇区
    mov cx, 1   
	;读取到 buf地址	
    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
	;调用中断(调用0x10号中断 打印)
    int 0x10
    ret

; no parameter
;重置软驱
ResetFloppy:
	;备份 ax bx 寄存器值,将ax bx 寄存器进栈备份
    push ax
    push dx
    
	;BIOS 中软盘数据读取 中断号0x13,参数(ah=0x00 软驱复位,dl=0 A盘)
	;软驱复位
    mov ah, 0x00
	;驱动器号 0:A盘
    mov dl, [BS_DrvNum]
	; BIOS 中软盘数据读取  中断号0x13
    int 0x13
    
	;将ax bx 寄存器出栈(恢复 ax bx 寄存器值),顺序与进栈顺序相反
    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
    ;bx(读取到的内存位置) cx(需要连续读取多少个扇区) 进栈备份
    push bx
    push cx
    
	;每个磁道扇区数 18
    mov bl, [BPB_SecPerTrk]
	; 执行除法操作,ax寄存器值/18 = 商位于 AL 寄存器中 余数位于 AH 寄存器中
    div bl
	;将 ah寄存器值(余数) 放到 cl寄存器
    mov cl, ah
	;三元素 之 扇区号
    add cl, 1
	;将 al寄存器值(商) 放到 ch寄存器
    mov ch, al
	;三元素 之 柱面号 (sh 寄存器值 右移一位)
    shr ch, 1
	
	;三元素 之 磁头号 商按位与1 == 磁头号  放在 dh寄存器
    mov dh, al
    and dh, 1
	
	;驱动器号
    mov dl, [BS_DrvNum]
    
	;将cx 寄存器值 出栈 并弹到 ax 寄存器中
    pop ax
    pop bx
    
	;BIOS 中软盘数据读取 中断号0x13,参数:
	; ah=0x02 从磁盘将数据读到ES:BX指向的内存
	; dl= 扇区长度,ch= 柱面号, cl=起始扇区号, dh=磁头号,dl=驱动器号 
    mov ah, 0x02

	;如果读取失败 则反复读取 直到读取成功
read:    
    int 0x13
	;读完后 查看错误标志位有没有被设置,有的话 跳转到read标签处重读
    jc read
    
	;出栈恢复(顺序相反)
    pop ax
    pop dx
    pop cx
    pop bx
    
    ret

MsgStr db  "Hello, DTOS!"  
;字符串长度: 用当前地址 - MsgStr 地址
MsgLen equ ($-MsgStr)
Buf:
    times 510-($-$$) db 0x00
    db 0x55, 0xaa
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/346573
推荐阅读
相关标签
  

闽ICP备14008679号