0

(私が読んだことから)ARM9プラットフォームはアライメントされていないメモリアドレスでデータを正しくロードできない可能性があるため、アドレス値が2の倍数ではない(つまり、16ビットでアライメントされていない)という意味でアライメントされていないと仮定しましょう。たとえば、適切に配置されたポインターが指す文字列の 4 番目の文字は?

char buf[] = "Hello world.";

buf[3]; // (buf + 3) is unaligned here,  is it not?

buf + 3適切にアラインされている場合とは対照的に、コンパイラは余分なコードを生成しますか? または、上記の例の最後のステートメントは、実行時に望ましくない結果をもたらしますlHello?

4

3 に答える 3

4

バイト アクセスはアラインする必要はありません。コンパイラはldrb、アライメントを一切必要としない命令を生成します。

理由について知りたい場合は、ARM がターゲット バイトを含むアライメントされたワード全体をロードし、ロードしたばかりの 4 つのバイトからそのバイトを選択するだけだからです。

于 2013-06-29T17:43:08.560 に答える
2

覚えておくべき概念は、プロセッサーの効率を最大限に高めるために、コンパイラーは型に基づいてアクセスを最適化しようとするということです。そのため、int にアクセスするときはldr、アラインされていないアクセスの場合にエラーになる命令などを使用する必要があります。アクセスにリンクするものについてcharは、コンパイラが詳細の一部を処理します。あなたが心配しなければならないのは、次のようなものです。

  • ポインターのキャスト。char *aを anにキャストしint *、ポインターが正しく配置されていない場合は、配置トラップが発生します。一般に、( anintから a にchar) キャスト ダウンしても問題ありませんが、その逆は問題ありません。あなたはこれをしたくないでしょう:

    char buf[] = "12345678";
    int *p = &buf[1];
    printf("0x%08X\n", *p);  // *p is badness here!
    
  • 構造体を使用してワイヤーからデータを引き出そうとしています。私はこれが多く行われているのを見てきましたが、それは単なる悪い習慣です。エンディアンの問題はさておき、要素がプラットフォームに対して正しく配置されていない場合、配置トラップが発生する可能性があります。

FWIW、ポインターのキャストは、おそらく私が実際に見た最大の問題です。

Write Portable Codeという素晴らしい本があり、複数のプラットフォーム用のコードを書くことについてかなり詳細に説明されています。リンクされたサイトのサンプルの章には、実際には配置について説明しているセクションが含まれています。

もう少し進行中のこともあります。のようなメモリ関数は、mallocアラインされたブロック (通常はダブルワード境界) を返すので、データを書き込んでもアラインメント フォールトにヒットすることはありません。

最後に、新しい ARM はアラインされていないアクセスにうまく対処できますが、パフォーマンスが高いというわけではありません。それは彼らが寛容であることを意味します。X86 プロセッサについても同じことが言えます。それらはアライメントされていないアクセスを行いますが、そうすることで余分なメモリ フェッチを強制しています。

于 2013-06-30T11:38:00.427 に答える