GetFATEntry详解,书上没讲清楚,转下别人的解释,不然真看不懂。

函数GetFATEntry。参数存放在ax寄存器中,表示一个簇号。输出结果是该簇号在FAT表中的FATENTRY,它的内容仍然是一个簇号,表示文件下一部分所在簇的簇号。这里要仔细地体会“簇号”和“簇”之间的差别,否则在看代码的时候,很容易就会迷失。“簇”表示一个或多个扇区的集合。FAT12中,一个簇就是一个扇区,512字节。簇号,从软盘的数据区开始,从2开始编号(0,1为系统使用),本质上是一个基于FAT表的索引。

GetFATEntry:
    push    es
    push    bx

;函数中使用到了es和bx所以要进行保存,保存在栈上。

;es:bx会被函数ReadSector所使用,是int 13h所要求的,指向了一个缓冲区,保存从软盘读进来的数据。
    push    ax
    mov    ax, BaseOfLoader
    sub    ax, 0100h   

;以上在BaseOfLoader之后留出4KB空间。为什么明明是0100h(256),怎么说是4K?

;因为这是个段基址,0100h还要乘上个16。
    mov    es, ax       
    pop    ax
    mov    byte [bOdd], 0
    mov    bx, 3
    mul    bx
    mov    bx, 2
    div    bx   
    cmp    dx, 0
    jz    LABEL_EVEN
    mov    byte [bOdd], 1

;以上部分是整个函数的难点所在,用户计算簇号在FAT表中所对应的FATENTRY相对于FAT首地址的偏移。

;从书上可以得知,FAT12中每个FATENTRY是12位的。所以如下:

7654 | 3210(byte1)    7654|3210(byte2)    7654|3210(byte3)

byte1和byte2的低4位表示一个Entry;根据Big-Endian,Entry内容为:3210(byte2)76543210(byte1)

byte3和byte2的高4位表示一个Entry;根据Big-Endian,Entry内容为:76543210(byte3)7654(byte2)

所以这里存在一个奇偶数的问题,以字节为单位。以上为例,Entry0偏移为0,Entry1偏移为1,Entry2偏移为3。

以INT[“簇号”*1.5]的方式增加。这也就是为什么上面先乘3再除2来计算。

根据DIV指令规定,商保存在ax中,余数在dx中。所以此时ax就是FATENTRY在FAT中以字节为边界的偏移量。

--------------------------------------------------------------------------------------------
LABEL_EVEN:
    xor    dx, dx   
    mov    bx, [BPB_BytsPerSec]
    div    bx   

;dx:ax/BPB_BytsPerSec,所以ax现在是扇区的个数,dx是在最后一个扇区中的偏移。
    push    dx
    mov    bx, 0   

;es:bx指向了目标空间的首地址,就是函数开始在BaseOfLoader之后留出的4KB空间。
    add    ax, SectorNoOfFAT1   

;SectorNoOfFAT1是FAT1的相对扇区号,物理上就是0面0道1扇区。FAT12有两个完全一样的FAT表,FAT1和FAT2。
    mov    cl, 2

;cl总保存ReadSector函数的参数,表示要连续读入2个扇区。另一个参数ax在前面已经给出。
    call    ReadSector   
    pop    dx
    add    bx, dx

;在add之前,bx为目标空间的首地址,其中内容是包含FATEntry的扇区。bx+dx就定位到了该FATEntry。
    mov    ax, [es:bx]

;ax中为es:bx指向的空间的内容。
    cmp    byte [bOdd], 1

;是奇数的簇号还是偶数的簇号??
    jnz    LABEL_EVEN_2
    shr    ax, 4

;7654 | 3210(byte1)    7654|3210(byte2)    7654|3210(byte3)

根据上面这个例子,奇数的簇号,1,偏移为1,所以读要ax中的时候,因为ax是16位,所以根据Big-Endian,ax的内容为7654|3210(byte3)|7654|3210(byte2),所以右移4位就可以了。

偶数簇号,0,偏移为0,读入ax后,ax的内容为7654|3210(byte2)7654 | 3210(byte1),我们只需要低12位即可,

所以and ax,0FFFh。

--------------------------------------------------------------------------------------------
LABEL_EVEN_2:
    and    ax, 0FFFh

LABEL_GET_FAT_ENRY_OK:

    pop    bx
    pop    es
    ret

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

robbie1314

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值