最近我在BrokenThorn上阅读了一些关于操作系统开发的好教程:这是一个很好的OSDev系列。
当我想加载引导加载程序的第2阶段时,我很难理解“计算下一个集群”的想法。代码是:
mov ax, WORD [cluster] ; The current Cluster.
mov cx, ax ; copy current cluster
mov dx, ax ; copy current cluster
shr dx, 0x0001 ; divide by two
add cx, dx ; sum for (3/2)
mov bx, 0x0200 ; location of FAT in memory
add bx, cx ; index into FAT
mov dx, WORD [bx] ; read two bytes from FAT
test ax, 0x0001
jnz .ODD_CLUSTER
jz .EVEN_CLUSTER
为什么我们将当前群集数乘以3/2以获得下一个群集号?
答案 0 :(得分:2)
我在汇编标签中找到了相同的问题,但是我找不到它来引用它! (非常有帮助)抱歉。
那么,为什么我们将索引乘以3/2来获取Next簇的索引?
首先,我们需要澄清一些想法:
FAT表格中的Enrty是什么?
长度为12位的内存和平。所以,FAT表是此条目的集合。
此条目中的内容是什么?
在这个内存的平静中有一个索引(Number),这个索引指的是同一个FAT表中的一个条目(FAT起始地址中有多少条目)。
每个条目长度为12位:
<---- 12 bits ----><---- 12 bits ----><---- 12 bits ----><---- 12 bits ---->
1st index 2nd index 3rd index 4th index
当我们从根目录获取第一个索引(例如:4)时,我们应该转到FAT表中的此索引以查找下一个簇编号的索引。我们将如何进行?
我们需要FAT表的起始地址(易于查找),并且只需添加索引。就像这样:
mov bx, [FAT address] ; Strat address of FAT table
mov ax, [cluster] ;the index (for ex: 4)
add bx, ax ;Start address + index = the next Entry (cluster).
容易:-) !!
但是3/2分数在哪里? :-D。
上面的代码是错的,为什么?
逻辑是正确的,但是对“寻址单元”存在误解
在大多数CPU中,单元寻址是 BYTE(8位),所以当我们将 [index] 表示为: index * 8-bit 在记忆中。
所以当我们做[cluster] ---&gt; index * 8-bit,像这样我们将索引8位长的条目。
与此相反,我们的索引是12位而不是8位!那么如何解决这个大问题呢?
解决方案:
我们应该将[cluster]乘以3/2,所以:
索引* 8位* 3/2 =索引* 12位。这就是我们需要的!现在我们可以通过12位单位(1.5字节)索引内存
正确的代码是:
mov bx, [FAT address] ; Strat address of FAT table
mov ax, [cluster] ;the index (for ex: 4)
mov dx, ax ; make copy of index
shr dx, 0x0001 ; divide it By 2.
add ax, dx ; index/2 + index = index * 3/2.
add bx, ax ;Start address + index = the next Entry (cluster).
我是新手,所以如果有什么不对,只需通知它;-D !! Thankx。
答案 1 :(得分:0)
这种奇怪之处特定于FAT12文件系统。
由于FAT12中簇的记录大小为12位,为了计算文件分配表中的偏移量(以字节为单位),您需要获取其索引并将其乘以3/2(或12位/ 8位) 。
群集记录包含文件或文件结束标记的下一个群集(如链接列表中的指针)的编号。对于免费群集,群集记录可能标记为坏群集或只是空闲群集。
答案 2 :(得分:0)
记住这是FAT12:每个群集是12位。因为一个字节是8位,一个条目是一个字节和一半,或3/2字节!