专注于操作系统27之对GetFATEntry函数的理解
来源:互联网 发布:小学生口语打分软件 编辑:程序博客网 时间:2024/03/29 10:31
在《自己动手写操作系统》的第四章中作者给出了这个函数。作者说这个函数的输入是扇区号,输出是其对应的fat项的值。我觉得说函数的输入是扇区号让人会产生疑惑,说函数的输入是Sector在FAT中的序号更恰当,在源代码中作者也是这么注释的。还有就是函数中有区别对待ax是奇数还是偶数。ax的值是Sector在FAT中的序号。这个函数的目的是根据这个序号,得到该序号所对应的fat项的值。一个fat项占1.5个字节。Sector在FAT中的序号是从0开始的。
当Sector在FAT中的序号是偶数时,假设为0(其实序号0在FAT是不会用的,但为了说明简单,其它偶数也是一样的)。下面给出一张图,图中fat0表示序号为0的fat项,ax是16位的,它存放了两个字节,而fat值是1.5个字节,即12位的,所以我们要把其它的四位置为0,当序号是偶数时,其它四位是ax中的高四位(源代码中是and ax,0fffh).
图中被红线划掉的部分表示不需要的4位。
当Sector在FAT中的序号为奇数时,假设为1(其实序号1在FAT是不会用的,但为了说明简单,其它奇数也是一样的)。下面给出一张图,图中fat1表示序号为1的fat项,ax是16位的,它存放了两个字节,而fat值是1.5个字节,即12位的,所以我们要把其它的四位置为0,当序号是奇数时,其它四位是ax中的低四位(源代码中是shr ax,4).
图中被红线划掉的部分表示不需要的4位。
下面是该函数的源代码
;----------------------------------------------------------------------------; 函数名: GetFATEntry;----------------------------------------------------------------------------; 作用:;找到序号为 ax 的 Sector 在 FAT 中的条目, 结果放在 ax 中;需要注意的是, 中间需要读 FAT 的扇区到 es:bx 处, 所以函数一开始保存了 es 和 bxGetFATEntry:pushespushbxpushaxmovax, BaseOfLoader ; ┓subax, 0100h; ┣ 在 BaseOfLoader 后面留出 4K 空间用于存放 FATmoves, ax; ┛popaxmovbyte [bOdd], 0movbx, 3mulbx; dx:ax = ax * 3movbx, 2divbx; dx:ax / 2 ==> ax <- 商, dx <- 余数cmpdx, 0jzLABEL_EVENmovbyte [bOdd], 1 ;表示ax为奇数LABEL_EVEN:;偶数xordx, dx; 现在 ax 中是 FATEntry 在 FAT 中的偏移量. 下面来计算 FATEntry 在哪个扇区中(FAT占用不止一个扇区)movbx, [BPB_BytsPerSec]divbx; dx:ax / BPB_BytsPerSec ==>ax <- 商 (FATEntry 所在的扇区相对于 FAT 来说的扇区号);dx <- 余数 (FATEntry 在扇区内的偏移)。pushdxmovbx, 0; bx <- 0于是, es:bx = (BaseOfLoader - 100):00 = (BaseOfLoader - 100) * 10haddax, SectorNoOfFAT1; 此句执行之后的 ax 就是 FATEntry 所在的扇区号movcl, 2callReadSector; 读取 FATEntry 所在的扇区, 一次读两个, 避免在边界发生错误, 因为一个 FATEntry 可能跨越两个扇区popdxaddbx, dxmovax, [es:bx]cmpbyte [bOdd], 1 ;比较是否为奇数,如果不是则转到LABEL_EVEN_2jnzLABEL_EVEN_2shrax, 4 ;为奇数时LABEL_EVEN_2: ;为偶数时andax, 0FFFhLABEL_GET_FAT_ENRY_OK:popbxpopesret;----------------------------------------------------------------------------
- 专注于操作系统27之对GetFATEntry函数的理解
- 专注于操作系统1之操作系统的从无到有a
- 专注于操作系统2之操作系统的从无到有b
- 专注于操作系统3之计算机的启动过程
- 专注于操作系统18之完整的特权级转换
- 专注于操作系统18之完整的特权级转换
- 专注于操作系统4之引导程序
- 专注于操作系统5之引导程序代码
- 专注于操作系统13之LDT
- 专注于操作系统15之特权级
- 专注于操作系统19之走进分页
- 专注于操作系统20之启动分页
- 专注于操作系统21之分页进阶
- 专注于操作系统22之中断
- 专注于操作系统23之中断进阶
- 专注于操作系统6之导入操作系统内核
- 专注于操作系统7之初识保护模式
- 专注于操作系统8之保护模式基础知识a
- ARM OS启动时的 堆栈初始化
- u-boot.ls 个人的简单解析
- vector.resize 与 vector.reserve的区别
- Oracle-undo-还原管理
- 打造U盘引导安装多系统
- 专注于操作系统27之对GetFATEntry函数的理解
- 学习笔记——XML简介和规则
- C++中构造函数调用构造函数
- ORA-24324:Service handle not initalized
- 正则表达式基础知识和ipv4的正则表达式
- Linux Run Levels
- dual表
- shutdown abort 的影响
- Oracle 用户管理