1

バイト配列から単語を読み取ることに関して、いくつかの混乱があります。バックグラウンド コンテキストは、イントロ コンピューター アーキテクチャ クラス用に C で記述された MIPS シミュレーターに取り組んでいるということですが、コードをデバッグしているときに、C プログラミングの観点からはまったく理解できない驚くべき結果に出くわしました。

次のように定義された mem というバイト配列があります。

uint8_t *mem;
//...
mem = calloc(MEM_SIZE, sizeof(uint8_t)); // MEM_SIZE is pre defined as 1024x1024

テスト中に、次のように uint32_t 値を 4 つのメモリ ブロックの mipsaddr というアドレスに一度に 1 バイトずつ手動で格納しました。

for(int i = 3; i >=0; i--) {
         *(mem+mipsaddr+i) = value;
         value = value >> 8;
         // in my test, value = 0x1084
}

最後に、2 つの方法のいずれかで配列から単語を読み取ることをテストしました。最初の方法では、基本的に単語全体を一度に変数に読み込もうとしました。

uint32_t foo = *(uint32_t*)(mem+mipsaddr);
printf("foo = 0x%08x\n", foo);

2 番目の方法では、各セルから各バイトを手動で読み取り、それらをビット シフトと共に加算しました。

    uint8_t test0 = mem[mipsaddr];
    uint8_t test1 = mem[mipsaddr+1];
    uint8_t test2 = mem[mipsaddr+2];
    uint8_t test3 = mem[mipsaddr+3];

    uint32_t test4 = (mem[mipsaddr]<<24) + (mem[mipsaddr+1]<<16) + 
               (mem[mipsaddr+2]<<8) + mem[mipsaddr+3];
    printf("test4= 0x%08x\n", test4);  

上記のコードの出力は次のようになりました: foo= 0x84100000 test4= 0x00001084

test4 の値は期待どおりですが、foo はバイトの順序が逆になっているようです。なぜこれが当てはまるのでしょうか?foo の場合、uint32_t* ポインターが mem[mipsaddr] を指していると予想しましたが、長さが 32 ビットであるため、配列に存在する順序で 32 ビットすべてを読み取るだけです (これは 00001084 になります)。 . 明らかに、私の理解は正しくありません。

私はここに来たばかりで、この質問に対する答えを検索しましたが、見つかりませんでした。既出でしたらすみません!しかし、そうでない場合は、誰かがここで私を啓発してくれることを願っています.

4

2 に答える 2

5

それは(とりわけ)ここで説明されています:http://en.wikipedia.org/wiki/Endianness

1 バイトを超えるデータをメモリに格納する場合、バイトが格納される順序はアーキテクチャ (手段、CPU) に依存します。最上位バイトが最初に格納され、最下位バイトが最後に格納されるか、またはその逆です。バイト アクセス操作によって個々のバイトを読み戻し、それらをマージして元の値を再び形成する場合、特定のシステムのエンディアンを考慮する必要があります。

forループでは、最上位バイトから始めて、値をバイト単位で保存しています(インデックスのカウントダウンは少し誤解を招きます;-)。その後、あなたの記憶は次のようになります。0x00 0x00 0x10 0x84.

次に、単一の 32 ビット (4 バイト) アクセスでワードを読み戻します。アーキテクチャに応じて、これは0x00001084(ビッグ エンディアン) または0x84100000(リトル エンディアン) になります。後者を取得したため、リトルエンディアン システムで作業しています。

2 番目のアプローチでは、個々のバイトを格納したのと同じ順序 (最上位が最初) を使用しているため、以前に格納したのと同じ値が返されます。

于 2012-10-05T05:59:47.800 に答える
0

エンディアンの問題のようです。おそらく (uint8_t *) から (uint32_t *) へのキャストが原因です。

于 2012-10-05T06:05:18.010 に答える