0

私が取り組んでいるプロジェクトでは、マジックナンバーを使用しています。このマクロは、マクロを定義するために使用されます

#define BOOTSIGNATURE 0xAA55

ただし、結果のファイルを HEXDUMP すると、AA55 と表示されるはずですが、55 AA と表示されます。

GCCはエンディアンを混同していますか、それとも私ですか? このプロジェクトは x86 プロセッサ用です。AA 55 はその特定の順序である必要があります。バイトを交換することもできますが、なぜ GCC がこれを行うのか興味があります。

4

4 に答える 4

2

0xAA55であるintため、マシンのエンディアンの影響を受けます。これをchar配列として格納します。

const unsigned char BOOTSIGNATURE[] = {0xAA, 0x55};
于 2012-11-09T20:48:17.223 に答える
2

プリプロセッサ マクロは、コンパイルされたオブジェクト ファイルには表示されません。コンパイラにはまったく表示されません。もしあなたがそれを持ってい#defineてどこにも使ったことがないなら、その痕跡はありません.

どこかのコードで使用した場合、命令の定数として表示される可能性があります (たとえば、定数をレジスタまたはメモリにロードするため)。これを使用して静的データを初期化すると、データ セグメントに定数として表示されます。

// Global variable definition
#define BOOTSIGNATURE 0xAA55
uint16_t my_global = BOOTSIGNATURE;

上記をコンパイルしてデータ セグメントを見ると、次のようになります。

$ gcc -c test.c
$ objdump -s test.o
[...]
Contents of section .data:
 0000 55aa0000                             U...

ご覧のとおり、2 バイトはリトル エンディアン順でメモリに格納されます55 AA(先頭0000は 16 進数のセグメント オフセットです)。

データのエンディアンを制御する場合は、明示的なバイト配列として格納します。

uint8_t my_global[] = {0xAA, 0x55};

これにより、バイトは常に指定された順序で格納されます。

于 2012-11-09T20:52:59.490 に答える
0

移植可能なコードを書きたい場合は、関数を使用して特定のバイト順を強制します。たとえば、これらの関数を使用すると、ネイティブ ホスト バイト順の 16 ビット値を、ファイル内で必要な順序に応じて、ビッグ エンディアンまたはリトル エンディアンに変換できます。

#define BOOTSIGNATURE 0xAA55

struct bootheader {
   uint16_t    signature_be;
} header;

header.signature_be = htobe16( BOOTSIGNATURE);

私は、ホストバイト順でない変数や構造要素にa_leまたはサフィックスを使用するのが好きです。_be

ビッグエンディアンが必要なので、htons()fromを使用できますarpa/inet.hが、私はその方法の大ファンではありません。名前は ほど明確ではないと思いますhtobe16。また、リトルエンディアンのバイト順との間で変換する関数がありません。

于 2012-11-15T01:46:51.477 に答える
-2

最も簡単な解決法: 整数形式の 16 進数値を使用して、対応するバイナリが同じマジック ナンバーになるようにします。この場合、それは 43605 になります

于 2012-11-09T21:01:22.653 に答える