第六课 突破512字节的限制 上

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

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

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

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

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

  4、中断调用(int 0x10)

示例如下:

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

              

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

 1 org 0x7c00
 2
 3 jmp short start
 4 nop
 5
 6 define:
 7     BaseOfStack equ 0x7c00
 8
 9 header:
10     BS_OEMName     db "D.T.Soft"
11     BPB_BytsPerSec dw 512
12     BPB_SecPerClus db 1
13     BPB_RsvdSecCnt dw 1
14     BPB_NumFATs    db 2
15     BPB_RootEntCnt dw 224
16     BPB_TotSec16   dw 2880
17     BPB_Media      db 0xF0
18     BPB_FATSz16    dw 9
19     BPB_SecPerTrk  dw 18
20     BPB_NumHeads   dw 2
21     BPB_HiddSec    dd 0
22     BPB_TotSec32   dd 0
23     BS_DrvNum      db 0
24     BS_Reserved1   db 0
25     BS_BootSig     db 0x29
26     BS_VolID       dd 0
27     BS_VolLab      db "D.T.OS-0.01"
28     BS_FileSysType db "FAT12   "
29
30 start:
31     mov ax, cs
32     mov ss, ax
33     mov ds, ax
34     mov es, ax
35     mov sp, BaseOfStack
36
37        mov ax, MsgStr
38        mov bp, ax
39
40        mov ax, ds
41        mov es, ax
42
43        mov cx, 6
44     call Print
45
46 last:
47     hlt
48     jmp last
49
50 ; es:bp --> string address
51 ; cx    --> string length
52 Print:
53     mov ax, 0x1301
54     mov bx, 0x0007
55     int 0x10
56     ret
57
58 MsgStr db  "Hello, DTOS!"
59 MsgLen equ ($-MsgStr)
60 Buf:
61     times 510-($-$$) db 0x00
62     db 0x55, 0xaa

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

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

 1 .PHONY : all clean rebuild
 2
 3 SRC := boot.asm
 4 OUT := boot.bin
 5 IMG := a.img
 6
 7 RM := rm -fr
 8
 9 all : $(OUT) $(IMG)
10     dd if=$(OUT) of=$(IMG) bs=512 count=1 conv=notrunc
11     @echo "Success!"
12
13 $(IMG) :
14     bximage [email protected] -q -fd -size=1.44
15
16 $(OUT) : $(SRC)
17     nasm $^ -o [email protected]
18
19 clean :
20     $(RM) $(IMG) $(OUT)
21
22 rebuild :
23     @$(MAKE) clean
24     @$(MAKE) all
25     

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

 1 ###############################################################
 2 # Configuration file for Bochs
 3 ###############################################################
 4
 5 # how much memory the emulated machine will have
 6 megs: 32
 7
 8 # filename of ROM images
 9 romimage: file=/usr/share/bochs/BIOS-bochs-latest
10 vgaromimage: file=/usr/share/vgabios/vgabios.bin
11
12 # what disk images will be used
13 floppya: 1_44=a.img, status=inserted
14 # choose the boot disk.
15 boot: a
16
17 # where do we send log messages?
18 # log: bochsout.txt
19
20 # disable the mouse
21 mouse: enabled=0
22
23 # enable key mapping, using US layout as default.
24 keyboard_mapping: enabled=1, map=/usr/share/bochs/keymaps/x11-pc-us.map

  

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

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

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

  3.5寸软盘的特性如下:

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

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

  整体的读取流程如下:

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

  

下面直接给出汇编程序:

  1 org 0x7c00
  2
  3 jmp short start
  4 nop
  5
  6 define:
  7     BaseOfStack equ 0x7c00
  8
  9 header:
 10     BS_OEMName     db "D.T.Soft"
 11     BPB_BytsPerSec dw 512
 12     BPB_SecPerClus db 1
 13     BPB_RsvdSecCnt dw 1
 14     BPB_NumFATs    db 2
 15     BPB_RootEntCnt dw 224
 16     BPB_TotSec16   dw 2880
 17     BPB_Media      db 0xF0
 18     BPB_FATSz16    dw 9
 19     BPB_SecPerTrk  dw 18
 20     BPB_NumHeads   dw 2
 21     BPB_HiddSec    dd 0
 22     BPB_TotSec32   dd 0
 23     BS_DrvNum      db 0
 24     BS_Reserved1   db 0
 25     BS_BootSig     db 0x29
 26     BS_VolID       dd 0
 27     BS_VolLab      db "D.T.OS-0.01"
 28     BS_FileSysType db "FAT12   "
 29
 30 start:
 31     mov ax, cs
 32     mov ss, ax
 33     mov ds, ax
 34     mov es, ax
 35     mov sp, BaseOfStack
 36
 37     mov ax, 34
 38     mov cx, 1
 39     mov bx, Buf
 40
 41     call ReadSector
 42
 43     mov bp, Buf
 44     mov cx, 24
 45
 46     call Print
 47
 48 last:
 49     hlt
 50     jmp last
 51
 52 ; es:bp --> string address
 53 ; cx    --> string length
 54 Print:
 55     mov ax, 0x1301
 56     mov bx, 0x0007
 57     int 0x10
 58     ret
 59
 60 ; no parameter
 61 ResetFloppy:
 62     push ax
 63     push dx
 64
 65     mov ah, 0x00
 66     mov dl, [BS_DrvNum]
 67     int 0x13
 68
 69     pop dx
 70     pop ax
 71
 72     ret
 73
 74 ; ax    --> logic sector number
 75 ; cx    --> number of sector
 76 ; es:bx --> target address
 77 ReadSector:
 78     push bx
 79     push cx
 80     push dx
 81     push ax
 82
 83     call ResetFloppy
 84
 85     push bx
 86     push cx
 87
 88     mov bl, [BPB_SecPerTrk]
 89     div bl
 90     mov cl, ah
 91     add cl, 1
 92     mov ch, al
 93     shr ch, 1
 94     mov dh, al
 95     and dh, 1
 96     mov dl, [BS_DrvNum]
 97
 98     pop ax
 99     pop bx
100
101     mov ah, 0x02
102
103 read:
104     int 0x13
105     jc read
106
107     pop ax
108     pop dx
109     pop cx
110     pop bx
111
112     ret
113
114 MsgStr db  "Hello, DTOS!"
115 MsgLen equ ($-MsgStr)
116 Buf:
117     times 510-($-$$) db 0x00
118     db 0x55, 0xaa

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

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

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

参考狄泰软件学院操作系统教程

  

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9226311.html

时间: 2025-01-18 01:16:34

第六课 突破512字节的限制 上的相关文章

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

突破限制的预备工作 整体思路 如何在根目录区中查找目标文件? 通过根目录项的前11个字节进行判断 内存比较 指定源起始地址(DS:SI) 指定目标起始地址(ES:DI) 判断在期望长度(CX)内每一个字节是否相等 汇编小贴士 汇编中的比较与跳转 比较: cmp cx, 0    :比较cx的值是否为0,并把结果记录到标志寄存器 跳转: jz equal          ; 如果比较为真(根据标志寄存器的值)就跳转到equal 访问栈空间中的栈顶数据 不能使用sp直接访问栈顶数据 通过其它通用寄

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

上一节我们写了字符串打印的函数和软盘读取函数,在软盘读取函数中,我们是直接给定了要读的逻辑扇区号,这一节我们来实现一个查找文件的功能,也就是根据给定的文件名,在根目录区中查找指定的文件是否存在,涉及到文件名的查找,就会涉及到内存的比较,因此,我们需要实现两个函数,分别为内存比较函数和根目录区查找函数. 整体的流程如下: 首先将根目录区加载到内存中的指定位置上,这里面包含了一定数目的根目录项,而根目录项的前11个字节为文件名,因此,查找文件的工作就可以进行了,我们只需要将目标文件名和每一个根目录项

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

上一节我们进行了文件的查找实验,文件查找成功了,这一节,我们将文件的内容加载进内存,再一次将整体的流程给出如下: 读取文件的内容时,我们需要根据FAT表找到存储文件内容的每一个扇区,然后进行内容的读取,在上一节中,我们将整个目录区的内容加载到了内存并根据文件名找到了所在的目录项,为了节省内存,我们将找到的目录项拷贝到另一片内存区域中,因为这个目录项中还有我们需要的内容,比如文件的起始扇区号等.而原来加载目录区的那一部分内存便可以另作他用,比如可以将FAT表加载到该区域. 目标文件的目录信息如下:

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

一.在突破512字节 Q:主引导程序中如何进行字符串打印?--直接打印A.BIOS中的字符串打印1.指定打印参数(AX=0x1301,BX=0x0007)--不借助循环2.指定字符串的内存地址(ES:BP=串地址)--通过段地址与段偏移来确定3.指定字符串的长度(CX=串长度)4.中断调用(int 0x10) B.汇编小贴士1.汇编中可以定义函数--函数名使用标签定义call function;函数体的最后一条指令为ret2.如果代码中定义了函数,那么需要定义栈空间主要用于保存关键寄存器的值:栈

【C语言探索之旅】 第二部分第六课:创建你自己的变量类型

0 内容简介 1.课程大纲 2.第二部分第六课: 创建你自己的变量类型 3.第二部分第七课预告: 文件读写 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算那点事 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创建你自己的变量

BeagleBone Black板第六课:C++编程控制GPIO基础

BBB板第六课:C++编程控制GPIO基础 在一上课我们通过Shell脚本编程实现了对GPIO端口的简单输出控制,实现对两个LED指示灯的交替点亮和关闭,接下来的一两节课,将通过C++程序来实现Shell脚本的功能.为了实现对应的程序控制,我查阅了好多资料,测试过程中发觉网上的一些程序套用过来总是出现各种各样的编译错误,压根就控制不了BBB板,不知是我的BBB板太新,还是以前的程序太旧.最后还是从头开始,重新研究BBB板的文件系统,找出头文件,找出所有相关的函数,终于实现GPIO的C++程序控制

NeHe OpenGL教程 第六课:纹理映射

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第六课:纹理映射 纹理映射: 在这一课里,我将教会你如何把纹理映射到立方体的六个面. 学习 texture map 纹理映射(贴图)有很多好处.比方说您想让一颗导弹飞过屏幕.根据前几课的知识,我们最可行的办法可能是很多个多边形来构建

OpenGL教程翻译 第十六课 基本的纹理贴图

OpenGL教程翻译 第十六课 基本的纹理贴图 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) Background 纹理贴图就是将任意一种类型的图片应用到3D模型的一个或多个面.图片(也可以称之为纹理)内容可以是任何东西,但是他们一般都是一些比如砖,叶子,地面等的图案,纹理贴图增加了场景的真实性.例如,对比下面的两幅图片. 为了进行纹理贴图,你需要进行三个步骤:将图片加载到OpenGl中,定义模型顶点的纹理坐标(以对其进行贴图),用纹理坐标对图片进行

2018-08-24 第三十六课

第三十六课 非关系统型数据库-mangodb 目录 二十四 mongodb介绍 二十五 mongodb安装 二十六 连接mongodb 二十七 mongodb用户管理 二十八 mongodb创建集合.数据管理 二十九 php的mongodb扩展 三十 php的mongo扩展 三十一 mongodb副本集介绍 三十二 mongodb副本集搭建 三十三 mongodb副本集测试 三十四 mongodb分片介绍 三十五 mongodb分片搭建 三十六 mongodb分片测试 三十七 mongodb备份