org 07c00h

;================================================
jmp short START
nop ; 这个 nop 不可少 ;这个结构将要被写在软盘的第一个扇区,相当于格式化软盘为FAT12格式
BS_OEMName DB 'PAVKOOOO' ; OEM String, 必须 8 个字节
BPB_BytsPerSec DW ; 每扇区512字节
BPB_SecPerClus DB ; 每簇1扇区 簇的定义是为了操作系统能够更加快速的去硬盘寻址,快速定位,而不只是使用扇区号
BPB_RsvdSecCnt DW ; 引导区使用1个扇区,不能有其他值,因为BIOS启动之后就会去取软盘的第一个扇区所有数据到内存,然后将控制权交给这个引导区
BPB_NumFATs DB ; 共有2 FAT 表 ;FAT格式(12,16,32)几乎都是2个表,第二个表用来备份。所以内容和第一个表完全一样
BPB_RootEntCnt DW ; 最多能存储224个文件??不清楚为什么是这个值
BPB_TotSec16 DW ; 逻辑扇区总数:FAT12的扇区个数=2个磁头*18个磁道*80个扇区 =2880
BPB_Media DB 0xF0 ; 媒体描述符 ??
BPB_FATSz16 DW ; 每FAT扇9个
BPB_SecPerTrk DW ; 每磁道18个扇区
BPB_NumHeads DW ; 磁头数(面数)
BPB_HiddSec DD ; 隐藏扇区数
BPB_TotSec32 DD ; 总扇区数,如果前面16位已经记录,这个就为0
BS_DrvNum DB ; 中断 13 的驱动器号
BS_Reserved1 DB ; 未使用
BS_BootSig DB 29h ; 扩展引导标记 (29h)
BS_VolID DD ; 卷序列号
BS_VolLab DB 'PAVKOOOOOOO'; 卷标, 必须 11 个字节
BS_FileSysType DB 'FAT12 ' ; 文件系统类型, 必须 8个字节 BaseofStack equ 07c00h
FileEntryBegin equ
CsOfLoader equ 010000h ;在实模式下,将loader.bin加载的内存地址应该为 07c00h+引导程序(512=200h)=07e00h之后
ipofLoader equ 0100h ;确保程序加载的内容在实模式寻址空间之内:1MB
FileEntryCount equ ;文件目录区所占用的扇区数
;=============引导程序开始执行====================
START:
xor eax,eax
mov ax,cs
mov ds,ax ;数据段,视频段,附加段都指向当前段
mov ss,ax
mov sp,BaseofStack ;栈顶ss:sp ==> 07C00h 也就是程序开始的位置 ,栈往低地址生长,这里没有做堆栈溢出检查 ;复位软驱
xor ah,ah
xor dl,dl
int 13h
;在软盘中读取1个扇区到内存
;因为loader.bin存在于根目录区,根目录区在扇区号19(0---引导扇区,1~9---FAT表1,10~18---FAT表2),所以需要将19扇区加载到内存
;整个目录区占用了多少个扇区? 224(个文件)*32(每个文件占用32个字节)/512(每个扇区512个字节) = 14 占用了14个扇区。
mov LoopSecNo,FileEntryBegin
BEGINREADSEC:
cmp LoopOfSec,
jz NOLOADER
dec LoopOfSec
mov ax,CsOfLoader
mov es,ax
mov ax,ipofLoader
mov bx,ax ;将数据读到es:bx指向的缓存中
mov ax,LoopSecNo
mov cl, ;只读1个扇区
call ReadSector ;读完之后,内存里就有512字节的内容了,现在还是寻找loader.bin
mov si, LoaderFileName ; ds:si -> "LOADER BIN"
mov di, ipofLoader
cld
mov dx, 10h
;一个扇区512 / 32有16(10H)个目录项
BEGINLOOPFILENAME:
;开始一个个项目的比较
cmp dx,
jz NEXTSECTOR ;到下一个扇区寻找,所以需要重新加载一个扇区
dec dx ;11个字母的文件名 ; ┛就跳到下一个 Sector
mov cx,
COMPARENAME:
cmp cx,
jz FILEFOUND ;文件找到了
dec cx
lodsb ; ds:si -> al
cmp al, byte [es:di]
jz NEXTCHAR
jmp NEXTFILE
NEXTCHAR:
inc di
jmp COMPARENAME
NEXTFILE:
and di, 0FFE0h loadsb会改变di,所以需要将di指定到文件条目的首地址
add di, 20h ;每个文件条目占有32个字符=20H
jmp BEGINLOOPFILENAME NEXTSECTOR:
add LoopSecNo,
jmp BEGINREADSEC NOLOADER:
jmp $ ;找不到的话,就卡死到这里
;如果文件找到了,就要把文件从数据区读取到内存
;目录区之后就是数据区,所以数据区的第一个扇区号是19+14=33!
FILEFOUND:
and di, 0FFE0h ; di -> 当前条目的开始
add di, 01Ah ;01Ah = 26 也就是文件条目地址偏移26的位置:DRI_FSTCLUS ;文件所在的数据区扇区号为:dir.DIR_FileSize -2 + 33 ==> [es:di]
mov word ax,[es:di];
push ax ;保存序号,getfatentry的时候需要使用
sub ax
add ax
LABEL_GOON_LOADING_FILE:
mov cl,
ReadSec ;loader.bin可能大于512字节,就是说可能超过1个扇区(不能超过两个,因为现在在实模式,实模式的最大寻址为1M)
;所以需要读取fat表,查看是否还有其他的扇区 pop ax
call GetFATEntry
cmp ax, 0FFFh
jz FILELOADED
;读取下一个未完的扇区
sub ax
add ax
;将数据读到es:bx指向的缓存中
add bx, [BPB_BytsPerSec] ; 读取的内存指针也应该后移512个字节(1个扇区)
jmp LABEL_GOON_LOADING_FILE FILELOADED:
; **********************
; 这一句正式跳转到已加载到内
; 存中的 LOADER.BIN 的开始处,
; 开始执行 LOADER.BIN 的代码。
; Boot Sector 的使命到此结束。
jmp CsofLoader:ipofLoader
; ********************** ;----------------------------------------------------------------------------
; 函数名: GetFATEntry
;----------------------------------------------------------------------------
; 作用:
; 找到序号DRI_FSTCLUS为 ax 的 Sector 在 FAT 中的条目, 结果放在 ax 中
; 需要注意的是, 中间需要读 FAT 的扇区到 es:bx 处, 所以函数一开始保存了 es 和 bx GetFATEntry:
push es
push bx
push ax
mov ax, CsOfLoader; `.
sub ax, 0100h ; | 在 BaseOfLoader 后面留出 4K 空间用于存放 FAT
mov es, ax ; /
pop ax
mov byte [bOdd],
mov bx,
mul bx ; dx:ax = ax * 3
mov bx,
div bx ; dx:ax / 2 ==> ax <- 商, dx <- 余数
cmp dx,
jz LABEL_EVEN
mov byte [bOdd],
LABEL_EVEN:;偶数
; 现在 ax 中是 FATEntry 在 FAT 中的偏移量,下面来
; 计算 FATEntry 在哪个扇区中(FAT占用不止一个扇区)
xor dx, dx
mov bx, [BPB_BytsPerSec]
div bx ; dx:ax / BPB_BytsPerSec
; ax <- 商 (FATEntry 所在的扇区相对于 FAT 的扇区号)
; dx <- 余数 (FATEntry 在扇区内的偏移)。
push dx
mov bx, ; bx <- 0 于是, es:bx = (BaseOfLoader - 100):00
add ax, SectorNoOfFAT1 ; 此句之后的 ax 就是 FATEntry 所在的扇区号
mov cl,
call ReadSector ; 读取 FATEntry 所在的扇区, 一次读两个, 避免在边界
; 发生错误, 因为一个 FATEntry 可能跨越两个扇区
pop dx
add bx, dx
mov ax, [es:bx]
cmp byte [bOdd],
jnz LABEL_EVEN_2
shr ax,
LABEL_EVEN_2:
and ax, 0FFFh LABEL_GET_FAT_ENRY_OK: pop bx
pop es
ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;如何函数使用INT 13读取软盘
;http://en.wikipedia.org/wiki/INT_13H
;传入扇区号到ax
;读取扇区数目到cl
;将数据读到es:bx指向的缓存中
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;在函数里面最好使用bp而不是使用SP
ReadSec:
push bp
mov bp,sp
sub sp,
mov bype [bp-],cl
push bx
mov bl,[BPB_SecPerTrk]
div bl ;扇区号/18; ah=余数,al=商
inc ah ;扇区号从0开始,所以需要加1
mov cl,ah
mov dh,al ;al表示磁道号
shr al, ;al / 2 的值为磁道号
mov ch,al
and dh, ;dh磁头号
mov dl=[BS_DrvNum]
pop bx
;int 13所需要的值都已经附了
LoopWhenFeild:
mov ah,
mov cl,[bp-]
int
jc LoopWhenFeild
add sp,
pop bp
ret ;-.- -.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.-!
;变量定义区
LoaderFileName db "LOADER BIN", ; LOADER.BIN 之文件名
LoopOfSec dw FileEntryCount;
LoopSecNo dw ;
bOdd db ; 奇数还是偶数
;---------------------------------------------------------------------------- times -($-$$) db ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志

FAT12格式的引导区实现的更多相关文章

  1. 【转载】FAT12格式的引导程序

    FAT12格式的引导程序 在上一篇文章中详细介绍了FAT12格式的引导扇区数据结构,详情请浏览: 地址是:http://blog.sina.com.cn/s/blog_3edcf6b80100cr08 ...

  2. 【转载】FAT12文件系统之引导扇区结构

    FAT12文件系统之引导扇区结构 文件系统即文件管理系统,是操作系统的重要组成部分之一,如果需要开发底层磁盘驱动或编写自己的操作系统,就必须详细了解文件系统. FAT12是Microsoft公司DOS ...

  3. 病毒木马查杀实战第024篇:MBR病毒之编程解析引导区

    前言 通过之前的学习,相信大家已经对磁盘的引导区有了充分的认识.但是我们之前的学习都是利用现成的工具来对引导区进行解析的,而对于一名反病毒工程师而言,不单单需要有扎实的逆向分析功底,同时也需要有很强的 ...

  4. (3)打造简单OS-MBR引导区转移加载简单程序(突破512限制)

    在第一节<(1)汇编写入引导区,虚拟机启动步骤>中讲解到一个简单屏幕显示一川字符串,第二节讲到BIOS启动过程! 第一节中基本原理就是将那个汇编代码用nasm汇编器进行汇编成二进制,然后把 ...

  5. (1)打造简单OS-汇编写入引导区,虚拟机启动步骤

    首先需要您在网上下载NASM编译器,可以将汇编编译为二进制文件 1.写一段汇编代码在屏幕上打印一段字符,可以运行的!并进行nasm为二进制文件,如下"test.asm" 该段汇编主 ...

  6. 【转载】FAT12格式的引导程序(2)

     1.用WinImage来写入到引导区的详细步骤: 启动WinImage后,打开“文件”菜单,单击菜单中的“打开”命令. 选择之前保存的磁盘镜像文件“boot.img”或者“boot.ima”. 打开 ...

  7. 如何在ubuntu下重建被grub覆盖的win10引导区?

    如何在ubuntu下重建被grub覆盖的win10引导区? 1.修改grub配置文件: sudo vi /etc/default/grub 2.设置:GRUB_DEFAULT = 2 3.更新配置文件 ...

  8. 病毒木马查杀实战第023篇:MBR病毒之引导区的解析

    前言 引导型病毒指寄生在磁盘引导区或主引导区的计算机病毒.这种病毒利用系统引导时,不对主引导区的内容正确与否进行判别的缺点,在引导系统的过程中入侵系统,驻留内存,监视系统运行,伺机传染和破坏.按照引导 ...

  9. linux 用dd命令读写引导区文件

    分类: LINUX 备份MBR,linux下使用如下命令: # dd if=/dev/hda of=/root/linux.bin bs=512 count=1 这里注意使用if=/dev/hda备份 ...

随机推荐

  1. ios中的奇怪崩溃Signal和EXC_BAD_ACCESS错误分析

    什么是Signal 在计算机科学中,信号(英语:Signals)是Unix.类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式.它是一种异步的通知机制,用来提醒进程一个事件已经发 ...

  2. SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块

    \(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...

  3. 洛谷 P1003 铺地毯

    嗯.... 一道比较水的模拟题.. 刚拿到题的时候被它的数据范围吓到了,二维数组不可能开那么大啊,可是一边做发现测试数据太水 ... 先看一下题吧... 题目描述 为了准备一个独特的颁奖典礼,组织者在 ...

  4. kindedtor的基本使用

    首先需要进入官网下载kineditor相关文件: 然后写代码: <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  5. php中静态绑定

    自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类. 虽然也可以调用非静态方法,但是不会在运行时绑定. static 不再只是简单的静态修饰关键字. ...

  6. 线段树 区间更新(更新区间[x,y]的值,再求任意区间[x,y]的和)

    #1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...

  7. stark组件之创建

    stark组件之需求 仿照Django中的admin , 开发了自己的stark组件,实现类似数据库客户端的功能,对数据进行增删改查 . stark之创建 1.在项目中 创建stark应用,app01 ...

  8. linux中文件压缩与打包

    一.常见的压缩命令 在linux环境中,压缩文件的扩展名大多是*.tar,*.tar.gz,*.tgz,*.gz,*.Z,*.bz2,首先我们来介绍以下这些压缩文案的扩展名:. *.Z:compres ...

  9. WIN2008R2 asp.net core的配置

    配置IIS Windows Server上通过“添加角色和功能”,桌面Windows上通过“启用和关闭Windows功能”来安装和配置IIS.确保勾选Web服务和“IIS 管理控制台”: Window ...

  10. Docker & ASP.NET Core 教程

    第一篇:把代码连接到容器 第二篇:定制Docker镜像 第三篇:发布镜像 第四篇:容器间的连接 第五篇: Docker & ASP.NET Core (5):Docker Compose AS ...