質問
以下のアセンブリコードでIはobjdump
を用いてダンプすることを
lea 0x0(%esi,%eiz,1),%esi
レジスタ%eiz
は何ですか?何が上記のコード意味ですか?
解決
明らか
%eiz
は擬似レジスタ(MIPS上r0
など)常にゼロにそれだけ評価されます。
...
私は最終的に答えを明らかにbinutilsの教祖イアン・ランス・テイラーメーリングリストのポストを見つけました。時には、GCCは、そのような適切なアライメントとスタッフを確保するために、コードストリームにNOP命令を挿入します。 NOP命令は、1つのバイトを取り、あなたは、必要に応じてあなただけの多くとして追加できると思うだろう。しかし、イアン・ランス・テイラーによると、それはより速く、多くの短い命令よりも一つの長い命令を実行するためのチップのためです。だから、むしろ7 NOP命令を挿入するよりも、彼らは代わりに7つのバイトを使用し、NOPと意味的に等価である1つのbizarroのLEAを、使用します。
他のヒント
:これは、すべてのレジスタはありません、それはインテルの命令エンコーディングの癖です。メモリからロードするMODRMバイトを使用する場合、8つの可能なレジスタを格納するレジスタ・フィールドのために使用される3ビットがあります。しかし、ESP(スタックポインタ)を代わりとしてプロセッサによって解釈される「なる」スポット「SIBバイトは、この命令に従う」(すなわち、その拡張アドレッシング・モードではなく、ESPを参照'S)。唯一の作者に知られている理由から、GNUアセンブラは常に「%のEIZ」登録として、この「レジスタはそうだろうゼロ」を表現しています。インテルの構文は、それをドロップします。
アンディ・ロスは、基礎となる推論のより多くを提供しますが、残念ながら間違っているか、非常に少なくとも、技術的な詳細について混乱します。それだけ(%esp)
の実効アドレスが代わり(%esp)
としてデコードされるのと同じくらいにModR / Mバイトで符号化することができないことは事実であり、SIBバイトも含まれていることを通知するために使用されます。しかし、%eiz
擬似レジスタは常にSIBバイトは使用されたことを表すために、SIBバイトでは使用されません。
SIBバイト(スケール/インデックス/塩基)は、それまでの3個を有する:インデックス(例えばスケールが適用されていることを%eax
又は%ecx
などとして登録)、スケール(1から8の2の累乗ことインデックスレジスタ)によって乗算され、ベース(スケーリングされたインデックスに追加される他のレジスタ)。 (またはIntel構文で、「BYTE PTR [ECXを追加 - :これは、このようなadd %al,(%ebx,%ecx,2)
(オペコード、MODR / mで、同胞(ノートなし%EIZ SIBバイトを使用したにもかかわらず登録)00 04 4b
マシンコード)として説明することができますものです* 2 + EBX]、ら」)。
しかし、%esp
は、SIBバイトのインデックスレジスタとして使用することはできません。代わりに、このオプションを可能にする、インテルではなく、スケーリングなしまたはインデックスであるようにベースレジスタを使用するオプションが追加されます。そしてadd %al,(%ecx)
(マシンコード:00 01
- オペコード、MODR / M、SIB) - :従ってadd %al,(%ecx)
の場合(オペコード、MODR / M 00 04 21
マシンコード)との間で明確にするために、代替構文add %al,(%ecx,%eiz,1)
代わりに(インテルまたは使用されています構文:add BYTE PTR [ecx+eiz*1],al
)
そしてシナンによって連結された記事で説明し、この特定の命令(lea 0x0(%esi,%eiz,1),%esi
)は単に一つのNOPのような命令は、複数のNOPの代わりに実行されなければならないように、マルチバイトNOP(esi = &*esi
に相当)として使用されますインストラクションます。