xor eax, eax
は常にeax
をゼロに設定しますよね?それで、なぜMSVC++は実行可能ファイルのコードにそれを入れるのですか? mov eax, 0
?
012B1002 in al,dx
012B1003 Push ecx
int i = 5;
012B1004 mov dword ptr [i],5
return 0;
012B100B xor eax,eax
また、in al, dx
?
はい、より効率的です。
オペコードはmov eax, 0
よりも短く、2バイトのみで、プロセッサは特殊なケースを認識し、eax
に対する誤った読み取り依存関係のないmov eax, 0
として処理します。したがって、実行時間は同じ。
また、バッファオーバーフローなどを悪用するためにシェルコードで使用されるようにコンパイルされたときに0を避けるために、なぜ0を避けるのですか?さて、0はc/c ++の文字列の終わりを表し、悪用の平均が文字列処理関数などの場合、シェルコードは切り捨てられます。
ところで、元の質問に言及している:「「xor eax、eax」を行う理由は何ですか?」 MSVC++コンパイラの機能ではありません。
これが実際の世界にどのように関係するかについてのコメントにはいくつかの議論があるので、 この記事 と Wikipediaのこのセクション を参照してください。
xor eax, eax
は、eax
をゼロに設定するより速い方法です。これは、ゼロを返しているために発生しています。
in
命令は、I/Oポートで何かを行っています。基本的にdx
で指定されたポートからWordのデータを読み取り、al
に保存します。ここでなぜ起こっているのかは明らかではありません。 参照 は、詳細を説明しているようです。
XOR操作は確かに非常に高速です。結果がレジスタをゼロに設定することである場合、コンパイラはしばしばそれが知っている最速の方法でそれを行います。XORに必要なCPUサイクルは1つだけですが、コピー(あるレジスタから別のレジスタへ)にはわずかな時間がかかります。
多くの場合、コンパイラの作成者は、ターゲットCPUアーキテクチャが異なると、動作も異なります。
XOR reg, reg
またはXORPS reg, reg
を使用するもう1つの理由は、依存関係チェーンを破壊することです。これにより、CPUはアセンブリコマンドの並列実行をより効率的に最適化できます(さらに命令スループットの前提を追加します)。