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は、2番目のバイトを10進数に変換していますか?またはビッグエンディアン形式に?なぜそれは最初のバイトではなく、2番目のバイトに対してのみ実行するのですか?

問題のバイトは[リトルエンディアン形式]です:

40 0B

最初に順序を切り替えて手動で変換してみました

0B 40

次に、16進数から10進数に変換すると、正しい出力が得られます。最初のバイトを2番目のバイトのビット単位のシフトに追加しても同じことがどのように行われるのかわかりません。ありがとう

4

3 に答える 3

4

ここでの使用malloc()は、真剣にの手のひらを誘発します。まったく不要で、深刻な「コードの臭い」(コードの全体的な品質を疑わせる)。また、mmap明らかにそうである必要がありますunsigned char(または、さらに良いuint8_t)。

そうは言っても、あなたが求めているコードは非常に単純です。

2つのバイトサイズの値aとが与えられた場合、それらを16ビット値に結合する2つの方法があります(これはコードが実行していることです)。最下位バイトとb見なすか、または。ab

ボックスを使用すると、16ビット値は次のようになります。

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

または、このように、代わりbに最上位バイトと見なす場合は、次のようになります。

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

lsbmsbを16ビット値に結合する方法 は次のとおりです。

result = (msb * 256) + lsb;

更新:256は、それがマルチバイト数の連続してより重要な各バイトの「価値」であるという事実に由来します。10進数での10の役割と比較してください(2つの1桁の10進数を組み合わせるにはcdを使用しますresult = 10 * c + d)。

とを考えるmsb = 0x01lsb = 0x00、上記は次のようになります。

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

msb予想どおり、バイトが16ビット値の上部にあることがわかります。

あなたのコードは、ビット単位で左にシフトするために使用しています。これは、2 8、つまり256<< 8を掛けるのと同じです。

result上記は値であり、つまりメモリ内のバイトバッファではないため、エンディアンは重要ではないことに注意してください。

于 2013-03-27T09:37:05.670 に答える
1

個々の数字またはバイトをより大きな整数に結合しても問題はありません。

2桁の小数を実行してみましょう:1(最下位)と2(最上位):

  1 + 2 * 10 = 21(10はシステムベース)

2桁の基数256を実行してみましょう:0x40(最下位)と0x0B(最上位):

  0x40 + 0x0B * 0x100 = 0x0B40(0x100 = 256がシステムベース)

ただし、問題は、12ビット整数がFAT12に格納される方法のどこかにある可能性があります。

12ビット整数は1.58ビットバイトを占有します。そして、3バイトには2つの12ビット整数があります。

これらの3バイトとして0x12、0x34、0x56があるとします。

最初の整数を抽出するには、最初のバイト(0x12)と2番目の最下位4ビット(0x04)を取得し、次のように組み合わせるだけです。

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

2番目の整数を抽出するには、2番目のバイト(0x03)と3番目のバイト(0x56)の最上位4ビットを取得し、次のように組み合わせる必要があります。

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

FATに関するMicrosoftの公式ドキュメント(fatgen103オンラインで検索)を読むと、FATに関連するすべての数式/擬似コードが見つかります。

于 2013-03-27T09:49:40.477 に答える
0

<<演算子は左シフト演算子です。演算子の左側の値を取り、演算子の右側で使用されている数値だけシフトします。

したがって、あなたの場合、*tmp28ビットの値を左にシフトし、それをの値と組み合わせて、*tmp12つの8ビット値から16ビット値を生成します。

たとえば、整数があるとします1。これは、16ビットバイナリでは、0000000000000001です。左に8ビットシフトすると、最終的には2進値0000000100000000、つまり25610進数になります。

プレゼンテーション(つまり、2進数、10進数、または16進数)はそれとは何の関係もありません。すべての整数は、コンピューターに同じ方法で保存されます。

于 2013-03-27T09:32:50.167 に答える