適用先: ARM 開発ツール
回答
この記事に含まれている情報の適用先:
- ARM 開発ツール
質問
RealView MDK-ARM を使用してアンアラインド メモリ アクセスをテストしています。簡単な例を以下に示します。
#pragma pack(1) unsigned char buf[40]; int main (void) { *((short *)&buf[0]) = 0x77ff; *((int *)&buf[2]) = 0x12345678; printf("%x %x %x %x ", buf[0], buf[1], buf[2], buf[3]); }
このコードはリトル エディアン マイクロコントローラ上で実行したため、出力結果は FF 77 34 12 になると予想していました。
しかし、得られた出力結果は、 78 56 34 12 でしたので、値 0x12345678 が buf[0] に書き込まれたようです。
何が間違っているのでしょうか?
回答
初期設定により、ARM7 および ARM9 ベースのマイクロコントローラでは、16ビットおよび 32ビット データ タイプへのアンアラインド アクセスが認められません。
Cortex-M3 ではアンアラインド アクセスもサポートされているため、上記のプログラムが正しく動作すると考えられます。
デバイスの実装に応じて、アンアラインド アクセスはデータ アボートまたはスワップ メモリ バイト(上記の例で表示された異常な出力)になる場合があります。
この挙動は、developer.arm.com 上で入手可能な CPU コアの Architecture Reference Manuals に記載されています。
この問題は、ワードまたはハーフワード アクセスの代わりにバイト アクセスを使用するようコンパイラに命令する __packed を使用して解決できます。
例えば、以下のコードでは、予想通りの結果が得られます。
unsigned char buf[40]; int main (void) { *((__packed short *)&buf[0]) = 0x77ff; *((__packed int *)&buf[2]) = 0x12345678; printf("%x %x %x %x ", buf[0], buf[1], buf[2], buf[3]); }
詳細
- ARM Architecture Reference Manual