57

次のアセンブリコードでは、以下を使用してダンプしましたobjdump

lea    0x0(%esi,%eiz,1),%esi

レジスターとは何%eizですか?上記のコードはどういう意味ですか?

4

3 に答える 3

59

なぜGCCLEAEIZなのかを参照してください。:

どうやら( MIPS%eizのように)常にゼロと評価される疑似レジスタです。r0

..。

私は最終的に、binutilsの第一人者であるIanLanceTaylorによる答えを明らかにするメーリングリストの投稿を見つけました。GCCは、コードストリームにNOP命令を挿入して、適切な配置などを保証する場合があります。NOP命令は1バイトかかるので、必要なだけ追加できると思います。しかし、Ian Lance Taylorによると、チップが1つの長い命令を実行する方が、多くの短い命令よりも高速です。したがって、7つのNOP命令を挿入するのではなく、代わりに1つの奇妙なLEAを使用します。これは、7バイトを使用し、意味的にはNOPと同等です。

于 2010-03-31T14:03:16.367 に答える
25

(ゲームに非常に遅れていますが、これは興味深い追加のように見えました):これはレジスターではなく、Intel命令エンコーディングの癖です。ModRMバイトを使用してメモリからロードする場合、8つの可能なレジスタを格納するためにレジスタフィールドに3ビットが使用されます。ただし、ESP(スタックポインタ)が「存在する」場所は、代わりにプロセッサによって「SIBバイトがこの命令に従う」と解釈されます(つまり、ESPへの参照ではなく、拡張アドレッシングモードです)。作者だけが知っている理由で、GNUアセンブラは常にこの「レジスタがなければゼロ」を「%eiz」レジスタとして表現してきました。Intel構文はそれを削除するだけです。

于 2012-08-28T17:06:57.433 に答える
14

Andy Rossは、根底にある推論の多くを提供していますが、残念ながら間違っているか、少なくとも技術的な詳細について混乱しています。(%esp)の実効アドレスは、としてデコードされるのではなく、ModR / Mバイトだけではエンコードできないことは事実です。これは(%esp)、SIBバイトも含まれていることを通知するために使用されます。ただし、%eizSIBバイトが使用されたことを表すために、疑似レジスタがSIBバイトとともに常に使用されるとは限りません。

SIBバイト(スケール/インデックス/ベース)には、インデックス(スケールが適用されるなどのレジスタ)、スケール(インデックスレジスタに乗算される1から8までの2の累乗)の3つの部分があり%eaxます%ecx。 by)、およびベース(スケーリングされたインデックスに追加される別のレジスタ)。これにより、add %al,(%ebx,%ecx,2)(マシンコード:00 04 4b-opcode、modr / m、sib(SIBバイトが使用されていても%eizレジスタがないことに注意してください))(またはIntel構文では "add BYTE PTR [ecx * 2 + ebx]、al ")。

ただし、%espSIBバイトのインデックスレジスタとして使用することはできません。このオプションを許可する代わりに、Intelは、スケーリングやインデックス付けなしでベースレジスタをそのまま使用するオプションを追加します。したがって、add %al,(%ecx)(マシンコード:00 01-opcode、modr / m)とadd %al,(%ecx)(マシンコード:00 04 21-opcode、modr / m、sib)の場合を明確にするために、代わりに代替構文add %al,(%ecx,%eiz,1)が使用されます(またはIntel構文の場合:) add BYTE PTR [ecx+eiz*1],al

また、Sinanがリンクしている記事で説明されているように、この特定の命令(lea 0x0(%esi,%eiz,1),%esi)は単にマルチバイトnop(と同等esi = &*esi)として使用されるため、複数のnop命令ではなく、1つのnopのような命令を実行するだけで済みます。

于 2014-01-15T04:06:13.123 に答える