2010-05-03 30 views
12

Preguntax86 instrucción CMP Diferencia

¿Cuál es el (no trivial) diferencia entre las dos siguientes instrucciones x86?

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

Antecedentes

Estoy construyendo un ensamblador de Java, que será utilizado por el lenguaje intermedio de mi compilador para producir Windows 32 ejecutables.

Actualmente tengo el código siguiente:

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

Para dar salida a un archivo ejecutable válido, que contiene dos instrucción CMP en una sección TEXTO. El ejecutable enviado a "text.exe" no hará nada interesante, pero ese no es el punto. La clase Compare es un contenedor alrededor de la instrucción CMP.

El código anterior produce (inspeccionando con OllyDbg):

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

La diferencia es sutil: si uso el 39 byte de código de operación:

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

que me pregunto sobre su sinonimia y por qué esto incluso existe.

Respuesta

18

No importa qué código de operación use si compara dos registros. La única diferencia es cuando se compara un registro con un operando de memoria, ya que el código de operación utilizado determina cuál será restado de cuál.

En cuanto a por qué esto existe: El formato de instrucción x86 utiliza el byte ModR/M para indicar una dirección de memoria o un registro. Cada instrucción solo puede tener un valor ModR/M, lo que significa que solo puede acceder a una dirección de memoria (sin incluir instrucciones especiales como MOVSB). Esto significa que no puede haber una instrucción general cmp r/m32, r/m32, y necesitamos dos códigos de operación diferentes: cmp r/m32, r32 y cmp r32, r/m32. Como efecto secundario, esto crea cierta redundancia al comparar dos registros.

+7

Estos grados de libertad de 1 bit también proporcionan un canal encubierto para que los compiladores puedan "llamar a casa": pueden "filtrar" los binarios que producen, y el proveedor del compilador puede pedirle que explique si encuentran su software con su marca de agua, pero sin licencia en el archivo. –

2

CMP ECX, EAX es ECX-EAX y CMP EAX, ECX es EAX-ECX. Los indicadores se configuran de manera diferente según el operando que se compara con el cual. Por supuesto, probablemente podría salirse con la suya solo si no fuera por la estructura mod/r-m de las instrucciones x86.

+1

El punto es que se puede codificar el mismo mnemónico de dos maneras diferentes porque hay un código de operación diferente para 'cmp r/m, r 'y' cmp r, r/m'. La pregunta es si el operando en MOD/RM que puede ser un operando de memoria es src1 o src2, y eso depende del código de operación. –

3

Es redundancy of x86. Hay muchos más casos como este. Un compilador/ensamblador es libre de usar cualquiera de los códigos de operación válidos

Algunos ensambladores le permiten elegir qué código de operación emitir. Por ejemplo en el gas puede adjuntar ".s" Para utilizar la otra codificación de instrucciones

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