2010-05-03 10 views
12

Domandax86 CMP istruzioni Differenza

Qual è il (non banale) differenza tra le due seguenti istruzioni x86?

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

Sfondo

Sto costruendo un'assembler Java, che sarà utilizzato per lingua intermedia del mio compilatore per produrre Windows 32 eseguibili.

Attualmente ho il codice seguente:

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

Per produrre un file eseguibile valido, che contiene due istruzione CMP in un testo-sezione. L'eseguibile inviato a "text.exe" non farà nulla di interessante, ma non è questo il punto. La classe Compare è un wrapper attorno all'istruzione CMP.

Il codice di cui sopra produce (ispezionando con OllyDbg):

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

La differenza è sottile: se uso il 39 byte opcode:

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

Il che mi fa chiedere circa la loro sinonimia e perché questo esiste anche.

risposta

18

Non importa quale codice operativo si utilizza se si confrontano due registri. L'unica differenza è quando si confronta un registro con un operando di memoria, poiché l'opcode utilizzato determina quale sarà sottratto da quale.

Per quanto riguarda perché esiste: il formato di istruzione x86 utilizza il byte ModR/M per indicare un indirizzo di memoria o un registro. Ogni istruzione può avere solo un valore ModR/M, il che significa che può accedere solo a un indirizzo di memoria (senza includere istruzioni speciali come MOVSB). Ciò significa che non può esistere un'istruzione generale cmp r/m32, r/m32 e che sono necessari due diversi codici opzionali: cmp r/m32, r32 e cmp r32, r/m32. Come effetto collaterale, questo crea una certa ridondanza quando si confrontano due registri.

+7

Questi gradi di libertà a 1 bit forniscono anche un canale segreto per i compilatori a "casa telefono" - possono "filigranare" i binari che producono, e il compilatore può chiederti di spiegare se trova il tuo software con la filigrana, ma senza licenza su file. –

2

CMP ECX, EAX è ECX-EAX e CMP EAX, ECX è EAX-ECX. I flag sono impostati in modo diverso a seconda di quale operando viene confrontato con il quale. Ovviamente probabilmente potresti farla franca solo con uno di essi se non fosse per la struttura mod/r-m delle istruzioni x86.

+1

Il punto è che è possibile codificare lo stesso mnemonico in due modi diversi, perché c'è un codice operativo diverso per 'cmp r/m, r 'e' cmp r, r/m'. La domanda è se l'operando in MOD/RM che può essere un operando di memoria è src1 o src2, e che dipende dall'opcode. –

3

È redundancy of x86. Ci sono molti più casi come questo. Un compilatore/assemblatore è libero di utilizzare uno qualsiasi dei codici opzionali validi

Alcuni assemblatori consentono di scegliere quale opcode emettere. Per esempio a GAS è possibile allegare ".s" per utilizzare l'altra codifica di istruzioni

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