我试图理解并实现一个基于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);
有效。是否按位<为什么它只对第二个字节而不是第一个字节?
所讨论的字节是[以小尾数格式]:
40亿
我试着先把顺序切换到
0B 40个
然后从十六进制转换为十进制,我得到了正确的输出,我只是不明白如何将第一个字节添加到第二个字节的按位移位中做同样的事情?
谢谢 最佳答案
这里使用的malloc()
是严重的facepalm诱导。完全没有必要,而且一种严重的“代码味道”(使我怀疑代码的整体质量)。而且,mmap
显然应该是unsigned char
(或者更好的是uint8_t
)。
也就是说,你要问的代码非常直截了当。
给定两个字节大小的值a
和b
,有两种方法可以将它们组合成16位值(这正是代码所做的):可以将a
视为最低有效字节,也可以将b
视为最低有效字节。
使用方框,16位值可以如下所示:
+---+---+
| a | b |
+---+---+
或者像这样,如果您认为b
是最有意义的字节:
+---+---+
| b | a |
+---+---+
将lsb
和msb
合并为16位值的方法很简单:
result = (msb * 256) + lsb;
更新:256来自于这样一个事实,即多字节数中每个连续的更有效字节的“值”。将其与十进制数中10的作用进行比较(要组合两个单位十进制数c
和d
,您可以使用result = 10 * c + d
)。
考虑到msb = 0x01
和lsb = 0x00
,则上述情况为:
result = 0x1 * 256 + 0 = 256 = 0x0100
您可以看到msb
字节结束于16位值的上部,正如预期的那样。
您的代码使用<< 8
执行向左的按位移位,这与乘以28(即256)相同。
注意,上面的result
是一个值,即不是内存中的字节缓冲区,所以它的endianness无关紧要。关于c - 在C中将Little Endian Hex转换为Big Endian十进制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15655467/