10

ウィキペディアのページのセグメンテーション違反によると、バスエラーはアラインされていないメモリアクセスによって引き起こされる可能性があります。この記事では、バスエラーをトリガーする方法の例を示しています。この例では、バスエラーを確認するためにアライメントチェックを有効にする必要があります。このようなアライメントチェックを無効にするとどうなりますか?

プログラムは正常に動作しているようです。私はプログラムがアラインされていないメモリに頻繁にアクセスし、それはかなりの数の人々によって使用されていますが、バスエラーやその他の奇妙な結果を私に報告する人は誰もいません。アラインメントチェックを無効にした場合、アラインされていないメモリの副作用は何ですか?

プラットフォーム: x86 / x86-64に取り組んでいます。また、Macで「gcc-arch ppc」を使用してプログラムをコンパイルしてみましたが、正常に動作します。

4

3 に答える 3

14
  1. アラインされていないメモリへのアクセスは大幅に遅くなる可能性があります(たとえば、数倍遅くなります)。

  2. すべてのプラットフォームが非整列アクセスをサポートしているわけではありません。たとえば、x86とx64はサポートしていますが、ia64(Itanium)はサポートしていません。

  3. コンパイラーは、整列されていないアクセスをエミュレートできます(たとえば、VC ++は、__unalignedia64で宣言されたポインターに対してそれを行います)-整列されていないケースを検出するための追加のチェックを挿入し、整列境界にまたがるオブジェクトの部分を個別にロード/格納します。ただし、これは、ネイティブにサポートしているプラ​​ットフォームでの非整列アクセスよりもさらに低速です。

于 2009-09-30T08:54:33.680 に答える
6

それはチップのアーキテクチャに大きく依存します。x86とPOWERは非常に寛容であり、Sparc、Itanium、VAXは異なる例外をスローします。

于 2009-09-30T09:05:46.843 に答える
2

ARM9でテストした次の例を考えてみましょう。

//Addresses       0     1     2    3     4     5     6     7      8    9
U8 u8Temp[10] = {0x11,0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00};

U32 u32Var;

u32Var = *((U32*)(u16Temp+1));  // Let's read four bytes starting from 0x22

// You would expect that here u32Var will have a value of 0x55443322 (assuming we have little endian)
// But in reallity u32Var will be 0x11443322!
// This is because we are accessing address which %4 is not 0.
于 2013-03-12T23:36:49.050 に答える