1

我正在尝试理解和实现一个基于 FAT12 的简单文件系统。我目前正在查看以下代码片段,它让我发疯:

int getTotalSize(char * mmap) { int *tmp1 = malloc(sizeof(int)); int *tmp2 = malloc(sizeof(int)); int retVal;

* tmp1 = mmap[19];
* tmp2 = mmap[20];
printf("%d and %d read\n",*tmp1,*tmp2);
retVal = *tmp1+((*tmp2)<<8);
free(tmp1);
free(tmp2);
return retVal;

};

从我目前所读到的,FAT12 格式以小端格式存储整数。上面的代码正在获取存储在引导扇区的第 19 和第 20 字节中的文件系统的大小。

但是我不明白为什么

  retVal = *tmp1+((*tmp2)<<8); 
作品。是按位 <<8 将第二个字节转换为十进制吗?还是大端格式?为什么它只对第二个字节而不是第一个字节?

有问题的字节是[小端格式]:

40 0B

我尝试通过先将顺序切换为手动转换它们

0B 40

然后从十六进制转换为十进制,我得到了正确的输出,我只是不明白如何将第一个字节添加到第二个字节的按位移位中做同样的事情?谢谢

4

3 回答 3

4

这里的使用malloc()是严重的面部诱导。完全没有必要,而且有严重的“代码异味”(让我怀疑代码的整体质量)。此外,mmap显然应该是unsigned char(或者,甚至更好,uint8_t)。

也就是说,您要询问的代码非常简单。

给定两个字节大小的值ab,有两种方法可以将它们组合成一个 16 位值(这就是代码所做的):您可以认为a是最低有效字节,或者b.

使用框,16 位值可以如下所示:

+---+---+
| a | b |
+---+---+

或者像这样,如果您改为认为b是最重要的字节:

+---+---+
| b | a |
+---+---+

lsb和组合msb成 16 位值的方法很简单:

result = (msb * 256) + lsb;

更新: 256 来自这样一个事实,即多字节数中每个连续更重要的字节的“价值”。将其与十进制数中 10 的作用进行比较(组合两个个位数的十进制数cd您将使用result = 10 * c + d)。

考虑msb = 0x01lsb = 0x00,那么上面将是:

result = 0x1 * 256 + 0 = 256 = 0x0100

您可以看到该msb字节在 16 位值的上半部分结束,正如预期的那样。

您的代码<< 8用于向左进行按位移位,这与乘以 2 8即 256 相同。

请注意,result上面是一个值,即不是内存中的字节缓冲区,因此它的字节顺序无关紧要。

于 2013-03-27T09:37:05.670 回答
1

我认为将单个数字或字节组合成更大的整数没有问题。

让我们用 2 位数字进行十进制:1(最低有效)和 2(最高有效):

  1 + 2 * 10 = 21(10 是系统基数)

现在让我们使用 2 位数字进行 base-256:0x40(最低有效)和 0x0B(最高有效):

  0x40 + 0x0B * 0x100 = 0x0B40 (0x100=256 是系统基数)

然而,问题可能在于其他地方,即 12 位整数如何存储在 FAT12 中。

一个 12 位整数占用 1.5 个 8 位字节。在 3 个字节中,您有 2 个 12 位整数。

假设您有 0x12、0x34、0x56 作为这 3 个字节。

为了提取第一个整数,您只需要获取第一个字节 (0x12) 和第二个字节 (0x04) 的 4 个最低有效位,然后像这样组合它们:

0x12 + ((0x34 & 0x0F) << 8) == 0x412

为了提取第二个整数,您需要获取第二个字节 (0x03) 和第三个字节 (0x56) 的 4 个最高有效位并将它们组合如下:

(0x56 << 4) + (0x34 >> 4) == 0x563

如果你阅读微软关于 FAT 的官方文档(fatgen103在线查找),你会发现所有与 FAT 相关的公式/伪代码。

于 2013-03-27T09:49:40.477 回答
0

<<运算符是左移运算符。它取运算符左侧的值,并将其移动运算符右侧使用的数字。

因此,在您的情况下,它将*tmp2八位的值向左移动,并将其与 的值组合*tmp1以从两个八位值生成一个 16 位值。

例如,假设您有 integer 1。这是,在 16 位二进制中,0000000000000001. 如果将其左移八位,则最终得到二进制值0000000100000000,即256十进制。

表示(即二进制、十进制或十六进制)与它无关。所有整数都以相同的方式存储在计算机上。

于 2013-03-27T09:32:50.167 回答