16

質問

次の2つのx86命令の(重要な)違いは何ですか?

39 /r    CMP r/m32,r32   Compare r32 with r/m32
3B /r    CMP r32,r/m32   Compare r/m32 with r32

バックグラウンド

私はJavaアセンブラーを構築しています。これは、コンパイラーの中間言語がWindows-32実行可能ファイルを生成するために使用します。

現在、私は次のコードを持っています:

final ModelBase mb = new ModelBase(); // create new memory model
mb.addCode(new Compare(Register.ECX, Register.EAX)); // add code
mb.addCode(new Compare(Register.EAX, Register.ECX)); // add code

final FileOutputStream fos = new FileOutputStream(new File("test.exe"));
mb.writeToFile(fos);
fos.close();

TEXTセクションに2つのCMP命令を含む有効な実行可能ファイルを出力します。「text.exe」に出力された実行可能ファイルは何も面白いことはしませんが、それは重要ではありません。クラスCompareCMP命令のラッパーです。

上記のコードは(OllyDbgで検査​​)を生成します:

Address   Hex dump                 Command
0040101F  |.  3BC8                 CMP ECX,EAX
00401021  |.  3BC1                 CMP EAX,ECX

違いは微妙です:39バイトオペコードを使用する場合:

Address   Hex dump                 Command
0040101F  |.  39C1                 CMP ECX,EAX
00401021  |.  39C8                 CMP EAX,ECX

それは私に彼らの同義性となぜこれが存在するのかについて疑問に思います。

4

2 に答える 2

21

2つのレジスタを比較する場合は、どちらのオペコードを使用してもかまいません。唯一の違いは、レジスタをメモリオペランドと比較する場合です。これは、使用されるオペコードによって、どちらがどれから減算されるかが決まるためです。

これが存在する理由について:x86命令フォーマットは、ModR / Mバイトを使用して、メモリアドレスまたはレジスタのいずれかを示します。各命令は1つのModR/M値のみを持つことができます。つまり、1つのメモリアドレスにしかアクセスできません(MOVSBなどの特別な命令は含まれません)。つまり、これは一般的なcmp r/m32, r/m32命令が存在できないことを意味し、2つの異なるオペコードが必要です:cmp r/m32, r32cmp r32, r/m32。副作用として、これにより2つのレジスタを比較するときに冗長性が生じます。

于 2010-05-03T20:15:44.553 に答える
6

x86の冗長性です。このようなケースはもっとたくさんあります。コンパイラ/アセンブラは、有効なオペコードを自由に使用できます

一部のアセンブラでは、発行するオペコードを選択できます。たとえば、GASでは、「。s」を付加して他の命令エンコーディングを使用できます。

10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh
于 2013-11-15T05:32:10.027 に答える