Question

Question

Quelle est la (non trivial) différence entre les deux instructions suivantes x86?

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

Historique

Je construis un assembleur Java, qui sera utilisé par le langage intermédiaire de mon compilateur pour produire des exécutables Windows 32.

Actuellement, j'ai code suivant:

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();

Pour fournir en sortie un fichier exécutable valide, qui contient deux instruction CMP dans un texte de section. L'exécutable émis vers « text.exe » fera intéressant rien, mais ce n'est pas le point. La Compare de classe est une enveloppe autour de l'instruction CMP.

Le code ci-dessus produit (inspection avec OllyDbg):

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

La différence est subtile: si j'utilise l'octet de code opération 39:

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

Ce qui me fait me demande au sujet de leur synonymie et pourquoi cela existe.

Était-ce utile?

La solution

Il n'a pas d'importance que vous utilisez opcode si vous comparez deux registres. La seule différence est lorsque l'on compare un registre avec un opérande de mémoire, comme l'opcode utilisé détermine qui sera soustrait à partir de laquelle.

Quant à savoir pourquoi cela existe: Le format d'instruction x86 utilise l'octet ModR / M pour désigner soit une adresse mémoire ou un registre. Chaque instruction ne peut avoir qu'une seule valeur ModR / M, ce qui signifie qu'il ne peut accéder d'une adresse mémoire (non compris les instructions spéciales comme MOVSB). Cela signifie donc qu'il ne peut y avoir une instruction de cmp r/m32, r/m32 générale, et nous avons besoin de deux opcodes différents: cmp r/m32, r32 et cmp r32, r/m32. Comme un effet secondaire, ce qui crée une certaine redondance lorsque l'on compare deux registres.

Autres conseils

redondance x86 . Il y a beaucoup plus de cas comme celui-ci. Un compilateur / assembleur est libre d'utiliser l'une quelconque des opcodes valides

Certains assembleur vous permet de choisir opcode d'émettre. Par exemple sur GAS vous pouvez attacher « .s » d'utiliser l'autre encodage d'instructions

10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh

CMP ECX, EAX est ECX-EAX et CMP EAX, ECX est EAX-ECX. Les indicateurs sont définis différemment selon opérande est comparée à qui. Bien sûr, vous pourriez probablement avec seulement un d'entre eux, s'il n'y avait pas la structure m r mod / x86 instructions.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top