19.3 对FAT的支持(harib16c)
19.3 对FAT的支持(harib16c)
问题:可以正确显示文件开头的512字节的内容,但大于512字节的部分不能正确显示(可能会显示其他文件)。
问题本质:磁盘可能将大于512字节的文件离散的保存在不同磁盘中。
解决办法:磁盘中保存了文件的下一段的地址。该记录(FAT,file allocation table,文件分配表)位于从0柱面、0磁头、2扇区开始的9个扇区中,由19.1 type命令(harib16a)中对磁盘映像在内存中的存储位置可知,该记录在内存中的地址是0x000200~0x0013ff。
下方便是磁盘映像中的FAT,由于FAT使用了微软的压缩算法,故需要解压。

解压算法:
压缩后 ---> 压缩后

直白的说,第一个字节(03)和第三个字节(00)的数据不变,将第二个字节的数据(40)拆开,分别与第一个字节和第三个字节进行拼接。
经过此番操作,解压后的FAT如下:

这里说明自己对为什么这么做可以节省空间的理解,FAT用于储存离散存储的文件块之间的线性关系,直白点说就是文件的下一段存储在哪个地方(扇区),故本质是存储磁盘号。有前面的知识,共2880个扇区,一个字节肯定是存不下(8位,无负数最大能表示的十进制值为256,此处不严谨,应考虑补码、类型等内容,但总之只用一个字节表示不了),但使用两个字节(WORD,沿用书上)16位又有些浪费(无负数最大能表示65536,同上,不严谨,参考数量级即可)。因此压缩,即用1.5字节(12位,4096)存储。参考书中,“磁盘共2880个扇区,正常使用WORD保存扇区号,FAT共需 2880×2=5760个字节,即一个FAT要占用12个扇区。 压缩后,3个字节可以保存2个扇区号,即存放1个扇区号需要的空间变为1.5个字节。因此,FAT总共需要2880×1.5=4320字节,一个FAT只占用9个扇区。 一张软盘中一共有2份FAT,因此经过压缩后,总共可以节省6个扇区的空间”
还有一点小思考,保持三字节存两扇区号的压缩方式不变,为什么不直接从中间一刀切,即将第二个字节的高四位直接并入第一个字节中,从其操作来说,似乎(只是在脑海中验证,并未写实际代码)开销差不多,代码的可读性也差不多?,不知道微软为什么要采用这种交叉的方式?
解压的代码如下:
void file_readfat(int *fat, unsigned char *img)
/* 将磁盘映像中的FAT解压缩 */
{
int i, j = 0;
for (i = 0; i < 2880; i += 2) {
fat[i + 0] = (img[j + 0] | img[j + 1] << 8) & 0xfff;/* 最后相与的目的是限制为 1.5字节*/
fat[i + 1] = (img[j + 1] >> 4 | img[j + 2] << 4) & 0xfff;
j += 3;
}
return;
}
代码解析如下:

- bootpack.h节选
void file_loadfile(int clustno, int size, char *buf, int *fat, char *img)
{
int i;
for (;;) {
if (size <= 512) {/* (注释错误)文件大小不大于一个扇区 */
for (i = 0; i < size; i++) {
buf[i] = img[clustno * 512 + i];
}
break;
}
for (i = 0; i < 512; i++) {/* 文件大小大于一个扇区 */
buf[i] = img[clustno * 512 + i];
}
size -= 512;
buf += 512;
clustno = fat[clustno];/* 寻找文件下一个存放的扇区 */
}
return;
}
注意:上面对于小于512的判断的作用是错误的(不全面),正确得应该是,一个一个扇区加载文件,若不够一个扇区(小于512),则只加载一部分(由size来确定加载到那部分)。整个文件小于一个扇区(512字节)的情况包含在其中
19.3 对FAT的支持(harib16c)的更多相关文章
- Spring Security(19)——对Acl的支持
目录 1.1 准备工作 1.2 表功能介绍 1.2.1 表acl_sid 1.2.2 表acl_class 1.2.3 表acl_obj ...
- 19. Spring Boot 添加JSP支持【从零开始学Spring Boot】
转:http://blog.csdn.net/linxingliang/article/details/52017140 这个部分比较复杂,所以单独创建一个工程来进行讲解: 大体步骤: (1) ...
- 【STM32H7教程】第19章 STM32H7的GPIO应用之按键FIFO
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第19章 STM32H7的GPIO应用之按键FIF ...
- Ubuntu的妥协将支持精选的32位应用
据外媒Tom's hardware,Ubuntu开发人员Canonical在早先的时候宣布Ubuntu 19.10将不再更新32位软件包和应用程序,引来了诸多应用开发者的不满.现在,Ubuntu方面宣 ...
- Java 19 新功能介绍
点赞再看,动力无限. 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Java 19 在2022 年 9 ...
- c语言知识点总结(摘自head first c)
gcc name.c -o name; ./name或者gcc name.c -o name && ./name;同时执行关键字:void sizeof(运算符,它能告诉你某样东 ...
- linux kernel menuconfig【转载】
原文网址:http://www.cnblogs.com/kulin/archive/2013/01/04/linux-core.html Linux内核裁减 (1)安装新内核: i)将新内核copy到 ...
- Zynq Fatfs文件系统应用笔记
Zynq Fatfs文件系统应用笔 Hello,panda 笔记介绍基于所描写叙述的Zynq Fatfs基于Xilinx xilffsv3.0和Sdpsv2.4,文件系统採用在Bare-Metal和轻 ...
- Android N开发 你需要知道的一切
title: Android N开发 你需要知道的一切 tags: Android N,Android7.0,Android --- 转载请注明出处:http://www.cnblogs.com/yi ...
- [Hadoop in Action] 第6章 编程实践
Hadoop程序开发的独门绝技 在本地,伪分布和全分布模式下调试程序 程序输出的完整性检查和回归测试 日志和监控 性能调优 1.开发MapReduce程序 [本地模式] 本地模式 ...
随机推荐
- kali linux|01.kali下安装Nessus
Kali安装Nessus 说明 Nessus是一款基于插件的系统漏洞扫描和分析软件 一.安装 1.下载安装包 https://www.tenable.com/downloads/nessus 查看ka ...
- jmeter性能测试学习1_配置oracl jdbc连接
1.导入orcle驱动的jar包 2.添加配置元件选择 JDBC连接配置 3.添加取样器 JDBCrequest 4.添加观察树,运行 配好密码 OK
- P3366 模板最小生成树
题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz. 输入格式 第一行包含两个整数N,M,表示该图共有N个结点和M条无向边. 接下来M行每行包含三个整数 Xi,Yi,Zi,表 ...
- Vue+SSM+Element-Ui实现前后端分离(1)
前言:最近学习vue,就突发奇想,小菜鸟的我是时候锻炼锻炼自己.闲话不说,整起 <-_-> 整体规划:先搭建前端,接下来后端,最后整合. 一.创建vue项目 1.安装nodejs( 傻瓜式 ...
- 【再学WPF】模板
1 <!--设置所有的按钮样式--> 2 <Style TargetType="Button"> 3 <Setter Property="M ...
- Qt之如何创建并显示一个柱状图
创建一个简单的柱状图 第一步:创建一个QBarSet对象:QBarSet类代表条形图中的一组条形. QBarSet *set0 = new QBarSet("Jane"); QBa ...
- Mysql 5.7 内存配置 (未完成)
innodb_buffer_pool_size = 4024024024 innodb 引擎,用于 缓存数据和索引
- awk sub string
cat TFY1C.txt|awk '{print $0"\t"substr($4,1,4)}'> TFY1CRID.tx 1--从那位开始 4--多长
- 005Java开发环境搭建
005Java开发环境搭建 1.JDK下载与安装 (1)卸载 首先我们先来学习一下如何卸载JDK. 删除Java的安装目录(jdk整个包). 删除环境变量里的"JAVA_HOME" ...
- idea导入数据库
yml文件(在启动项文件(main)里,eg:springbook文件里面) sh-bean里org.example.sh.beans的Category类 CategoryDAO名字要和Categ ...