私は、主に IDA だけでなく gdb も使用して、x86 で Linux elf 実行可能ファイルを見てきました。私が気付いたことの 1 つは、関数は常にワード境界で整列されたアドレスにロードされるということですか? その理由を知っている人はいますか?アラインされたアドレスで開始する x86 命令の要件を認識していません。また、ページ境界が関数内のどこにでもある可能性があるため、ページの配置が原因ではありません。
洞察をいただければ幸いです。
ありがとう。
そうです、指示を揃える必要はありません。x86 プロセッサでは、アセンブリ命令は 1 ~ 15 バイト以上の可変長コードを使用してエンコードされます。
ただし、命令は通常 64 バイトにアラインされたキャッシュから読み取られ、コードが正しくアラインされていると、実行パイプラインの一部 (デコード、ループ、分岐予測など) がより高速に動作します。
これに関する最良の情報源は、Agner Fog のドキュメントです: http://www.agner.org/optimize/
一部のアーキテクチャでは、データの配置によって、操作ごとにコピーできるデータの量が決まります。たとえば、アドレス 0x4000 から 32 ビットをコピーしようとすると、32 ビットの移動操作が 1 回必要になる場合があります。0x4001 から 32 ビットをコピーするには、8 ビットの移動操作が 4 回必要になる場合があります。さらに、ミスアラインされたアドレスで 32 ビット移動命令を使用すると、ハードウェア例外が発生する可能性があります。ハードウェア例外は、一度に 8 ビットをコピーすることによって処理されますが、アライメントされたアドレスからコピーするよりも遅くなります。
編集:
これは、実行されるデータだけでなく、すべてのデータに適用されます。そのため、関数のエントリ ポイントは、スイッチ ターゲット、文字列定数、グローバル、およびその他のデータと共に配置されます。