06 突破512字节的限制 上

https://www.cnblogs.com/wanmeishenghuo/tag/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/

https://blog.51cto.com/13475106/category6.html

及狄泰软件相关课程

 

前几节我们介绍了FAT12文件系统,制作了虚拟软盘文件a.img,并在Qt Creater中进行了文件内容的读取实验。那些读取都是使用外部的程序实现的,实际应用中,我们需要用主引导程序来实现文件的读写,主引导程序存在于主引导扇区MBR中,也就是说程序和文件是存在一张盘上的,而且这些主引导程序需要使用汇编语言实现。接下来,我们就来实现具有读取功能的主引导程序。

  为了验证文件读取的正确性,我们需要在主引导程序中先实现一个字符串打印函数。BIOS已经将中断向量写到了内存的指定位置处,这其中就有能实现字符串打印的函数,我们需要做的就是配置一些参数,需要配置的参数和配置步骤如下:

  1、指定打印参数(AX=0x1301 , BX = 0x0007)

  2、指定字符串的内存地址(ES:BP  = 字符串地址)

  3、指定字符串的长度(CX = 字符串长度)

  4、中断调用(int 0x10)

示例如下:

  需要用到的汇编语言的知识点如下:

                                

  下面直接给出打印字符串的汇编程序:

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
org 0x7c00
 
jmp short start
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, MsgStr
       mov bp, ax
 
       mov ax, ds
       mov es, ax
 
       mov cx, 6
    call Print
 
last:
    hlt
    jmp last
 
; es:bp --> string address
; cx    --> string length
Print:
    mov ax, 0x1301
    mov bx, 0x0007
    int 0x10
    ret
 
MsgStr db  "Hello, DTOS!"
MsgLen equ ($-MsgStr)
Buf:
    times 510-($-$$) db 0x00
    db 0x55, 0xaa

我们的虚拟软盘文件a.img已经格式化好了,现在要修改的只是第一个扇区即主引导扇区,所以我们要按照FAT12的格式来填充第一个扇区,因此,上面的程序中,第10到28行是FAT12的引导扇区的信息,它前面还有三个字节,其中前两个字节是跳转指令jmp short start,第三个字节为空指令nop。从start开始是我们的可执行程序,BaseOfStack是定义的栈底地址。

  汇编程序我们需要编译成二进制可执行程序,然后写入a.img虚拟软盘的第一个扇区中,每次都执行这个过程很麻烦,我们将这个过程写成makefile,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.PHONY : all clean rebuild
 
SRC := boot.asm
OUT := boot.bin
IMG := a.img
 
RM := rm -fr
 
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

bochs的启动文件修改成如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
###############################################################
# Configuration file for Bochs
###############################################################
 
# how much memory the emulated machine will have
megs: 32
 
# filename of ROM images
romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin
 
# what disk images will be used
floppya: 1_44=a.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/share/bochs/keymaps/x11-pc-us.map

启动bochs,即可得到运行结果,如下所示:

 

  可见,hello已经成功打印出来了。

   接下来,我们开始读取文件,假如我们知道了数据所在的扇区,那么怎么将它读出来呢?先来看一下软盘的构造,如下所示:

  3.5寸软盘的特性如下:

  根据逻辑扇区号计算磁头号、柱面号、物理扇区号的方法如下:

  软盘复位和软驱数据读取的参数如下:

 

  整体的读取流程如下:

  需要用到的汇编知识点如下:

  

 下面直接给出汇编程序:

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
org 0x7c00
 
jmp short start
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
    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)
Buf:
    times 510-($-$$) db 0x00
    db 0x55, 0xaa

  

我们将虚拟软盘文件a.img用VS2013打开,查看其中的内容,截取片段如下:

  可以看到,a.txt文件的起始地址为0x4400,也就是第34个扇区开始,而内容的大小为24字节,这两个参数分别体现在汇编程序中的第37和44行。下面,启动bochs,运行结果如下:

打印出了this is a floppy file.,我们成功读取了指定扇区的数据。

 

      若有问题,可以使用bochs环境进行汇编代码调试,具体通过反汇编,结合运行地址和断点调试来进行,可以观察指令执行情况

及相关寄存器的值,可参考本节相关教程。

 

小结
1.当汇编代码中定义了函数,那么需要定义栈空间
2.读取数据前,逻辑扇区号需要转化为磁盘的物理位置
3.物理软盘上的数据位置由磁头号,柱面号,扇区唯一确定
4.软盘数据以扇区512为单位进行读取

 

 

  

  

  

  

posted on   lh03061238  阅读(203)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2018-11-13 source命令用法详解
2018-11-13 Linux /etc/profile文件详解

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示