15

次の種類のエンディアンの違いは何ですか?

  • バイト (8b) 不変のビッグ エンディアンとリトル エンディアン
  • ハーフワード (16b) 不変のビッグエンディアンとリトルエンディアン
  • 単語 (32b) 不変のビッグ エンディアンとリトル エンディアン
  • ダブルワード (64b) 不変のビッグエンディアンとリトルエンディアン

他のタイプ/バリエーションはありますか?

4

8 に答える 8

28

エンディアン マッピングには、アドレス不変性データ不変性の 2 つのアプローチがあります。

アドレスの不変性

このタイプのマッピングでは、バイトのアドレスは常に大きなものと小さなものの間で保持されます。これには、特定のデータ (2 バイトまたは 4 バイトのワードなど) の重要度の順序 (最上位から最下位) が逆になり、データの解釈が逆になるという副作用があります。具体的には、リトル エンディアンでは、データの解釈は最下位バイトから最上位バイトへと行われますが、ビッグ エンディアンでは、解釈は最上位バイトから最下位バイトへと行われます。どちらの場合も、アクセスされるバイトのセットは同じままです。

アドレスの不変性 (バイトの不変性とも呼ばれます): バイト アドレスは一定ですが、バイトの意味が逆になります。

Addr   Memory
       7    0
       |    |    (LE)   (BE)
       |----|
 +0    | aa |    lsb    msb
       |----|
 +1    | bb |     :      :
       |----|
 +2    | cc |     :      :
       |----|
 +3    | dd |    msb    lsb
       |----|
       |    |

At Addr=0:          Little-endian          Big-endian
Read 1 byte:              0xaa                0xaa   (preserved)
Read 2 bytes:           0xbbaa              0xaabb
Read 4 bytes:       0xddccbbaa          0xaabbccdd

データの不変性

このタイプのマッピングでは、特定のサイズのデータ​​に対して相対的なバイトの重要度が保持されます。したがって、さまざまなデータ サイズに対してさまざまなタイプのデータ不変エンディアン マッピングがあります。たとえば、32 ビット ワードの不変エンディアン マッピングは、32 のデータ サイズに使用されます。特定のサイズのデータ​​の値を保持する効果は、データ内のバイトのバイト アドレスが、ビッグ エンディアン マッピングとリトル エンディアン マッピングの間で逆になることです。 .

32 ビット データの不変性 (ワードの不変性0xddccbbaaとも呼ばれます): データは、エンディアンに関係なく常に値を持つ 32 ビットのワードです。ただし、1 ワードより小さいアクセスの場合、ビッグ エンディアン マッピングとリトル エンディアン マッピングの間でバイトのアドレスが逆になります。

Addr                Memory

            | +3   +2   +1   +0 |  <- LE
            |-------------------|
+0      msb | dd | cc | bb | aa |  lsb
            |-------------------|
+4      msb | 99 | 88 | 77 | 66 |  lsb
            |-------------------|
     BE ->  | +0   +1   +2   +3 |


At Addr=0:             Little-endian              Big-endian
Read 1 byte:                 0xaa                    0xdd
Read 2 bytes:              0xbbaa                  0xddcc
Read 4 bytes:          0xddccbbaa              0xddccbbaa   (preserved)
Read 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)

16 ビット データの不変性 (ハーフ ワードの不変性0xbbaaとも呼ばれます): データは、エンディアンに関係なく常に値を持つ 16 ビットです。ただし、ハーフ ワードより小さいアクセスの場合、ビッグ エンディアン マッピングとリトル エンディアン マッピングの間でバイトのアドレスが逆になります。

Addr           Memory

            | +1   +0 |  <- LE
            |---------|
+0      msb | bb | aa |  lsb
            |---------|
+2      msb | dd | cc |  lsb
            |---------|
+4      msb | 77 | 66 |  lsb
            |---------|
+6      msb | 99 | 88 |  lsb
            |---------|
     BE ->  | +0   +1 |


At Addr=0:             Little-endian              Big-endian
Read 1 byte:                 0xaa                    0xbb
Read 2 bytes:              0xbbaa                  0xbbaa   (preserved)
Read 4 bytes:          0xddccbbaa              0xddccbbaa   (preserved)
Read 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)

64 ビット データの不変性 (ダブル ワードの不変性0x99887766ddccbbaaとも呼ばれます): データは、エンディアンに関係なく常に値を持つ 64 ビット ワードです。ただし、ダブル ワードより小さいアクセスの場合、ビッグ エンディアン マッピングとリトル エンディアン マッピングの間でバイトのアドレスが逆になります。

Addr                         Memory

            | +7   +6   +5   +4   +3   +2   +1   +0 |  <- LE
            |---------------------------------------|
+0      msb | 99 | 88 | 77 | 66 | dd | cc | bb | aa |  lsb
            |---------------------------------------|
     BE ->  | +0   +1   +2   +3   +4   +5   +6   +7 |


At Addr=0:             Little-endian              Big-endian
Read 1 byte:                 0xaa                    0x99
Read 2 bytes:              0xbbaa                  0x9988
Read 4 bytes:          0xddccbbaa              0x99887766
Read 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)
于 2008-09-14T23:46:37.037 に答える
4

フィリバートは言った、

ビットは実際に反転されました

アーキテクチャがバイト値の不変性を破るとは思えません。ビットフィールドを含む構造体をデータに対してマッピングする場合、ビットフィールドの順序を反転する必要がある場合があります。このような直接マッピングは、C99 標準の外側にあるコンパイラの仕様に依存していますが、まだ一般的である可能性があります。ダイレクト マッピングは高速ですが、パッキング、アラインメント、およびバイト オーダーを規定しない C99 標準には準拠していません。C99 準拠のコードでは、アドレスではなく値に基づくスロー マッピングを使用する必要があります。つまり、これを行う代わりに、

#if LITTLE_ENDIAN
  struct breakdown_t {
    int least_significant_bit: 1;
    int middle_bits: 10;
    int most_significant_bits: 21;
  };
#elif BIG_ENDIAN
  struct breakdown_t {
    int most_significant_bits: 21;
    int middle_bits: 10;
    int least_significant_bit: 1;
  };
#else
  #error Huh
#endif

uint32_t data = ...;
struct breakdown_t *b = (struct breakdown_t *)&data;

これを書く必要があります(これは、コンパイラが上記の「直接マッピング」に対してもコードを生成する方法です)、

uint32_t data = ...;
uint32_t least_significant_bit = data & 0x00000001;
uint32_t middle_bits = (data >> 1) & 0x000003FF;
uint32_t most_significant_bits = (data >> 11) & 0x001fffff;

各エンディアンニュートラルなアプリケーション固有のデータストレージユニットでビットフィールドの順序を逆にする必要がある理由は、コンパイラがビットフィールドを成長するアドレスのバイトにパックするためです。

各バイトの「ビットの順序」は重要ではありません。それらを抽出する唯一の方法は、値のマスクを適用し、最下位ビットまたは最上位ビットの方向にシフトすることです。「ビットの順序」の問題は、ビットアドレスの概念を持つ架空のアーキテクチャでのみ重要になります。私は、すべての既存のアーキテクチャがこの概念をハードウェアに隠し、エンディアン中立のバイト値に基づく概念である最下位ビットと最上位ビットの抽出のみを提供していると考えています。

于 2010-08-27T04:29:59.587 に答える
3

ミドルエンディアンまたは混合エンディアンもあります。詳細については、ウィキペディアを参照してください。

私がこれについて心配しなければならなかったのは、C でネットワーク コードを記述するときだけでした。ネットワークでは通常、ビッグ エンディアンの IIRC が使用されます。ほとんどの言語は、すべてを抽象化するか、適切なエンディアンを使用していることを保証するライブラリを提供します。

于 2008-08-21T23:57:39.673 に答える
1

エンディアンについて読んだ最高の記事「ビッグエンディアンとリトルエンディアンのバイトオーダーを理解する」。

于 2008-08-22T01:57:42.600 に答える
1

実際には、マシンのエンディアンをビットの順序ではなく、ワード内のバイトの順序として説明します。

そこまでの「バイト」とは、「アーキテクチャが個別に管理できるメモリの最小単位」を意味します。したがって、最小単位が 16 ビット長 (x86 ではwordと呼ばれる) の場合、値 0xFFFF0000 を表す 32 ビットの「単語」は次のように格納できます。

FFFF 0000

またはこれ:

0000 FFFF

エンディアンに応じてメモリ内。

したがって、エンディアンが 8 ビットの場合、16 ビットで構成されるすべてのワードが次のように格納されることを意味します。

FF 00

また:

00 FF

等々。

于 2008-08-22T00:39:51.520 に答える
0

実際には、エンディアンとは、プロセッサが特定のメモリ位置のコンテンツを解釈する方法を指します。たとえば、次の内容(16進バイト)のメモリ位置0x100がある場合


  0x100:  12 34 56 78 90 ab cd ef

Reads    Little Endian            Big Endian
 8-bit:  12                        12
16-bit:  34 12                     12 34
32-bit:  78 56 34 12               12 34 56 78
64-bit:  ef cd ab 90 78 56 34 12   12 34 56 78 90 ab cd ef

エンディアンを気にする必要がある2つの状況は、ネットワークコードの場合と、ポインターを使用してダウンキャストを行う場合です。

TCP / IPは、ネットワーク上のデータがビッグエンディアンであることを指定しています。バイト配列以外の型(構造体へのポインターなど)を送信する場合は、データがビッグエンディアンで送信されるように、必ずntoh/htonマクロを使用する必要があります。リトルエンディアンプロセッサからビッグエンディアンプロセッサに(またはその逆に)送信すると、データが文字化けします...

キャストの問題:


 uint32_t* lptr = 0x100;
 uint16_t  data;
 *lptr = 0x0000FFFF

 data = *((uint16_t*)lptr);

データの価値はどうなりますか?ビッグエンディアンシステムでは0になりますリトルエンディアンシステムではFFFFになります

于 2008-09-16T01:53:37.173 に答える
0

13年前、私はDECALPHAシステムとPCの両方に移植可能なツールに取り組みました。このDECALPHAでは、ビットは実際に反転されていました。あれは:

1010 0011

実際に翻訳された

1100 0101

私がビットフィールドを次のように宣言したことを除いて、Cコードではほとんど透過的でシームレスでした

typedef struct {
   int firstbit:1;
   int middlebits:10;
   int lastbits:21;
};

これを変換する必要がありました(#ifdef条件付きコンパイルを使用)

typedef struct {
   int lastbits:21;
   int middlebits:10;
   int firstbit:1;
};
于 2008-09-16T03:27:04.627 に答える
-1

基本的な概念はビットの順序付けです:

1010 0011

リトルエンディアンでは

0011 1010

ビッグエンディアンで(およびその逆)。

個々のビットではなく、グループ化によって順序が変わることに気付くでしょう。たとえば、どこのシステムかわかりません

1100 0101

最初のバージョンの「別のエンディアン」バージョンになります。

于 2008-08-21T23:49:01.923 に答える