8

リトル エンディアン/ビッグ エンディアンについて混乱があります。私は単純なものが欠けているようです。いくつかのフィードバックをいただければ幸いです。たとえば、
32 ビット値の最下位バイトと最上位バイトを取得する 2 つの関数があるとします。

#define LSB(x) ((x) & 0x000000FF)

#define MSB(x) ((x) & 0xFF000000)

私の質問は: 上記の 2 つの関数は、ビッグエンディアンとリトル エンディアン両方のマシンで正しい結果を返しますか?

ここで、なぜ私が混乱しているのかを説明します。リトル エンディアンのマシンを使用していると想像してください。リトルエンディアン マシンでは、整数 9 は次のように (16 進数で) メモリに格納されます: 09 00 00 00 (最下位バイトが最初) ある時点で、上記の LSB 関数を使用すると、次のようになると思うかもしれません。そのような式: 09 00 00 00 & 00 00 00 FF これは 0 です - もちろん、それは LSB 関数を超える方法が最終的に機能する方法ではありません。だから私はsmthが欠けているようです。どんな助けでも感謝します。

またint y = 0x000000FF、マシンのエンディアンに関係なく、これは 255 ですよね?

4

6 に答える 6

12

エンディアンに関係なく、x & 0xFF最下位バイトが表示されます。

まず、エンディアンと意味の違いを理解する必要があります。エンディアンとは、バイトがメモリに書き込まれる順序を意味します。CPU での計算にはまったく関係ありません。重要性は、どのビットがより高い値を持つかを示します。ストレージのシステムとはまったく関係ありません

メモリから CPU に値をロードすると、CPU (より正確には ALU) にとって重要なのはビットの意味だけであるため、エンディアンは問題になりません。

したがって、Cに関する限り、0x000000FF最下位バイトに1がありand、変数でそれをingすると最下位バイトが得られます。


実際、C 標準全体では、「エンディアン」という言葉は見つかりません。C は、ビットの意味だけが重要な「抽象マシン」を定義します。エンディアンに関係なく、抽象マシンと同じように動作するようにプログラムをコンパイルするのは、コンパイラの責任です。したがって、メモリの特定のレイアウト (たとえば、unionまたはポインタのキャスト) を想定していない限り、エンディアンについて考える必要はまったくありません。


あなたが興味を持つかもしれない別の例はシフトです。同じことがシフトにも当てはまります。実際、前に述べたように、エンディアンは ALU にとって重要ではないため、エンディアン<<に関係なく、常にコンパイラではなく CPU 自体によってより重要なビットにシフトするように変換されます。


これらを直交する 2 つの方向のグラフにまとめてみましょう。これは、ロード操作が CPU の観点からどのように見えるかです。

リトルエンディアンのマシンでは、次のようになります。

         MEMORY            CPU Register

  LSB BYTE2 BYTE3 MSB  ---->   MSB
    \    \     \----------->  BYTE3
     \    \---------------->  BYTE2
      \-------------------->   LSB

ビッグ エンディアンのマシンでは次のようになります。

         MEMORY            CPU Register

      /-------------------->   MSB
     /    /---------------->  BYTE3
    /    /     /----------->  BYTE2
  MSB BYTE3 BYTE2 LSB  ---->   LSB

ご覧のとおり、どちらの場合も次のようになります。

CPU Register

    MSB
   BYTE3
   BYTE2
    LSB

つまり、どちらの場合も、CPU はまったく同じ値をロードすることになりました。

于 2013-10-16T16:33:39.587 に答える
0

エンディアンは、メモリの使用方法に関するものです。バイトをメモリ、ストレージ、または何らかのストリームにシリアライズまたはデシリアライズするときは、主にこれについて心配する必要があります。

マクロは使い方次第でうまくいくこともあれば、うまくいかないこともあると思います。x が int の場合 (32 ビットの int を使用していると仮定)、問題が発生する可能性がある x が 32 ビットの数値でない場合、コンパイラは int とは何か、および int がどのように表現されるかを認識しているため、問題ありません。

于 2013-10-16T16:37:48.833 に答える