バイト順
マイクロプロセッサ・アーキテクチャは、一般に、マルチバイト数値データの個々のバイトをメモリに格納するために 2 つの異なる方法を使用します。この違いは、"バイト順" または "エンディアンの性質" と呼ばれます。ほとんどの場合、コンピュータのエンディアン形式は安全に無視できますが、状況によっては非常に重要になります。OS X は、あるエンディアンのデータを別のエンディアンに変換するためのさまざまな機能を提供します。
Intel x86 プロセッサは、最下位バイトを最初に、続いて最上位バイトの順序で 2 バイト整数を格納します。これをリトルエンディアンバイト順と呼びます。PowerPC CPU のような他の CPUは、最上位バイトを最初に、続いて最下位バイトの順番で 2 バイト整数を格納します。これをビッグエンディアンバイト順と呼びます。ほとんどの場合、コンピュータのエンディアン形式は安全に無視できますが、状況によっては非常に重要になります。たとえば、あなたのコンピュータとは異なるエンディアンからデータを読み取ろうとすると、バイト順の違いによって不正な結果が生じる可能性があります。ネットワークからデータを読み取るときにも同じ問題が発生する可能性があります。
エンディアン形式の問題を議論する具体的な例を示すために、リスト 1 に示すように 2 つの 4 バイト整数を定義する単純な C 構造体の場合を考えてみましょう。
リスト 1 データ構造体の例
struct { UInt32 int1; UInt32 int2; } aStruct;
リスト 2 に示すコードを使用して、リスト 1 に示す構造体を初期化するものとします。
リスト 2 例に挙げた構造体の初期化
ExampleStruct aStruct; aStruct.int1 = 0x01020304; aStruct.int2 = 0x05060708;
ビッグエンディアンのプロセッサまたはメモリシステムが例に挙げたデータをどのように構成するかを示す 図 1 の図形を考えてみます。ビッグエンディアンシステムでは、物理メモリは、各バイトのアドレスが最上位から最下位まで増加するように構成されています。
図 1 ビッグエンディアン形式のデータ例
フィールドには、左側に上位バイト、右側に下位バイトが格納されていることに注意してください。これは、アドレスフィールド Int1 の最上位バイトのアドレスが 0x98 であり、アドレス 0x9B が Int1 の最下位バイトに相当することを意味します。
図 2 の図形は、リトルエンディアンシステムがどのようにデータを編成するかを示しています。
図 2 リトルエンディアン形式のデータ例
各フィールドの最下位アドレスは、現在、最上位バイトの代わりに最下位バイトに対応していることに注意してください。リトルエンディアンシステムで Int1 の値を印刷する場合、別のバイト順で格納されているにもかかわらず、10 進数値 16909060 として正しく解釈されます。
リスト 2 に示すコードで初期化された例のデータ値がリトルエンディアンシステムで生成され、ディスクに保存されたとします。データがバイトアドレス順でディスクに書き込まれると仮定しましょう。ビッグエンディアンシステムによってディスクから読み取られると、図 2 に示すように、データは再びメモリーに配置されます。問題は、データがビッグエンディアンシステムで解釈されていても、 リトルエンディアンのバイト順である事です。この違いにより、値は正しく評価されません。この例では、フィールド Int1 の十進数値は 16909060 でなければなりませんが、不正なバイト順のため、67305985 と評価されます。この現象はバイトスワッピングと呼ばれ、あるエンディアン形式のデータが他のエンディアン形式を使用するシステムで読み込まれた時起こります。
残念ながら、これは一般的な場合には解決できない問題です。理由は、スワップする方法がデータの形式に依存するためです。文字列は通常まったくスワップされません。ロングワードは 4 バイトの逆さまにスワップされたものを受け取り、ワードは 2 バイトのさかさまにスワップされたものを受け取ります。したがって、データをスワップする必要のある全てのプログラムは、データ型、ソースデータのエンディアン順、およびホストのエンディアン順を把握している必要があります。
CFByteOrder.h の関数を使用すると、浮動小数点値だけでなく、2 バイトおよび 4 バイト整数のバイトスワップを実行できます。これらの関数を適切に使用することで、プログラムが処理するデータが正しいエンディアン順であることを確認するのに役立ちます。これらの関数の使用法の詳細については、バイトスワップ を参照して下さい。Core Foundation のバイトスワッピング関数は、OS X でのみ使用できる事を注意して下さい。
前の章 次の章