ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

06 突破512字节的限制 上

2020-11-13 10:33:32  阅读:222  来源: 互联网

标签:BPB 06 字节 db mov 扇区 BS ax 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)

示例如下:

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

                                

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

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,如下所示:

.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的启动文件修改成如下内容:

###############################################################
# 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寸软盘的特性如下:

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

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

 

  整体的读取流程如下:

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

  

 下面直接给出汇编程序:

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, 24

    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为单位进行读取

 

 

  

  

  

  

标签:BPB,06,字节,db,mov,扇区,BS,ax,512
来源: https://www.cnblogs.com/lh03061238/p/13967949.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有