8 ビット プロセッサのメモリ (たとえば 8051) に int32 型の整数がある場合、その整数のエンディアンを特定するにはどうすればよいでしょうか? コンパイラ固有ですか?これは、シリアル回線などでマルチバイト データを送信する場合に重要だと思います。
7 に答える
より広い整数をネイティブでサポートしていない 8 ビット マイクロコントローラでは、メモリに格納される整数のエンディアンは、コンパイラの作成者次第です。
8051 で広く使用されている SDCC コンパイラは、整数をリトル エンディアン形式で格納します (そのコンパイラのユーザー ガイドでは、データ ポインタをインクリメントする命令が存在するため、そのアーキテクチャの方が効率的であると主張していますが、1 つではありません)。デクリメント用)。
プロセッサにマルチバイト値に作用する操作がある場合、またはマルチバイト レジスタがある場合、エンディアン性を持つ可能性があります。
http://69.41.174.64/forum/printable.phtml?id=14233&thread=14207は、8051 がさまざまな場所でさまざまなエンディアンを混在させていることを示唆しています。
それはコンパイラ次第ではありません-'51には、コンパイラが従わなければならない特定のエンディアンネスのネイティブ16ビットレジスタ(DPTR、標準のPC、バリアントのADC_IN、DAC_OUTなど)があります-しかし、それ以外では、コンパイラは好みのエンディアン、またはプロジェクト構成で選択したエンディアンを自由に使用できます...
エンディアンは、CPU アーキテクチャに固有です。コンパイラは特定の CPU をターゲットにする必要があるため、コンパイラはエンディアンも認識しています。そのため、シリアル接続やネットワークなどを介してデータを送信する必要がある場合は、ビルトイン関数を使用してデータをネットワーク バイト オーダーに配置することをお勧めします。特に、コードが複数のアーキテクチャをサポートする必要がある場合はそうです。
詳細については、http ://www.gnu.org/s/libc/manual/html_node/Byte-Order.html を参照してください。
整数にはエンディアンがありません。ビッグエンディアンなのかリトルエンディアンなのかは、バイト数を見ただけでは判断できません。知っておく必要があること: たとえば、8 ビット プロセッサがリトル エンディアンで、ビッグ エンディアンであることがわかっているメッセージを受信した場合 (たとえば、フィールド バス システムがビッグ エンディアンを定義しているため)、値を変換する必要があります。 8ビット以上。それをハードコーディングするか、システム上でバイトをスワップする定義を行う必要があります。
バイトの交換は簡単なことであることに注意してください。ビット フィールド内のビットの順序はコンパイラ固有であるため、ビット フィールド内のビットをスワップする必要がある場合もあります。繰り返しますが、基本的にビルド時にこれを知っておく必要があります。
unsigned long int x = 1;
unsigned char *px = (unsigned char *) &x;
*px == 0 ? "big endian" : "little endian"
x に値 1 が割り当てられている場合、値 1 は最下位バイトになります。次に、x をバイトへのポインターにキャストすると、ポインターは x の最下位のメモリ位置を指します。そのメモリ ロケーションが 0 の場合はビッグ エンディアン、それ以外の場合はリトル エンディアンです。
#include <stdio.h>
union foo {
int as_int;
char as_bytes[sizeof(int)];
};
int main() {
union foo data;
int i;
for (i = 0; i < sizeof(int); ++i) {
data.as_bytes[i] = 1 + i;
}
printf ("%0x\n", data.as_int);
return 0;
}
出力の解釈はあなた次第です。