2010-01-25 8 views
25

que estaba buscando a través de la disassmbly de mi programa (ya que se estrelló), y se dio cuenta un montón de¿Por qué Visual Studio uso hacha xchg, hacha

xchg ax, ax 

busqué en Google y descubrí que es esencialmente un nop, pero ¿Por qué Visual Studio hace un xchg en lugar de un noop?

la aplicación es una aplicación de 64 bits C# .NET3.5, compilado por el estudio visual

+1

¿Los bytes asociados con estas instrucciones son los mismos? nop debe ser hex 90. ¿xchg ax, ax a 2 byte instruction? –

+0

Esto resultó ser una pregunta con un poco más de matiz de lo que originalmente pensé (o recuerdo de todos modos). –

+0

oye, ¿puedes decirme cómo mirar el código de ensamblaje como el tuyo? Me gustaría ver cómo un simple prgoram se convierte en ensamblaje. gracias – masfenix

Respuesta

33

En x86 la instrucción NOPesXCHG AX, AX

Las 2 instrucciones mnemónicas se reúnen para la misma op- binario código. (En realidad, supongo que un ensamblador podría usar cualquier xchg de un registro consigo mismo, pero AX o EAX es lo que normalmente se usa para el nop hasta donde yo sé).

xchg ax, ax tiene las propiedades de cambiar los valores de registro y no cambiar las banderas (hey - it's a op!).


Editar (en respuesta a un comentario de Anon.):

Ah, claro - Ahora recuerdo que hay varias codificaciones para la instrucción xchg. Algunos toman un conjunto de bits mod/r/m (como muchas instrucciones de arquitectura Intel x86) que especifican una fuente y un destino. Esas codificaciones toman más de un byte. También hay una codificación especial que usa un solo byte e intercambia un registro de propósito general con (E)AX. Si el registro especificado también es (E)AX si tiene una instrucción NOP de un solo byte. también puede especificar que (E)AX se intercambie consigo mismo utilizando la variante más grande de la instrucción xchg.

supongo que MSVC utiliza la versión de múltiples bytes de xchg con (E)AX como el origen y el destino cuando se quiere masticar más de un byte para ninguna operación - que lleva el mismo número de ciclos como el único byte xchg , pero usa más espacio. En el desmontaje no verá el byte múltiple xchg decodificado como NOP, incluso si el resultado es el mismo.

Específicamente xchg eax, eax o nop podría codificarse como códigos de operación o 0x900x87 0xc0 dependiendo de si usted quiere que utilizar hasta 1 o 2 bytes. El desensamblador de Visual Studio (y probablemente otros) decodificará el código de operación 0x90 como la instrucción NOP y decodificará el código de operación 0x87 0xc0 como xchg eax, eax.

Ha sido un tiempo desde que he hecho trabajos que se detallan en lenguaje ensamblador, lo más probable es que estoy equivocado en al menos un recuento aquí ...

+0

Entonces, ¿por qué también veo nop? – Malfist

+0

Ese sería el desensamblador siendo inteligente (o tonto, dependiendo de lo que quisieras que hiciera). ¿Ves ambas decodificaciones usando el mismo desensamblador? Eso podría ser algo interesante de mirar. –

+0

Es el desensamblador de estudio visual ... – Malfist

8

xchg ax,ax y nop son en realidad la misma instrucción, que se asignan a el mismo código de operación (0x90 iirc). Está bien, xchg ax,axes a No-Op. ¿Por qué debería uno perder codificaciones de código de operación adicionales con instrucciones que no hacen nada?

Cuestionable es por qué ve ambos mnemotécnicos impresos.Supongo que es solo un error en el desmontaje, no hay diferencia binaria.

+1

0x90 not 90 ... .. – Earlz

+0

La cuestión de si se pierden las codificaciones de código de operación en las instrucciones de no hacer nada plantea algunos problemas interesantes, especialmente en arquitecturas que se especifican para interceptar instrucciones no válidas. Por un lado, si una parte significativa del espacio de código de operación es utilizada por instrucciones funcionalmente idénticas, prohibir el uso de todas esas codificaciones, excepto una, haría que las demás estén disponibles para operaciones futuras. Por otro lado, hacerlo podría dificultar algunos escenarios de generación de códigos dinámicos, y si se supone que los códigos de operación no válidos están atrapados, se requiere hardware adicional para atraparlos. – supercat

+0

@supercat: Eso es un poco diferente a simplemente declinar definir * otro código de operación * que no hace nada, ¿no es así? – SamB

4

MSVC pone NOP en el código compilado para compilaciones de depuración, en general. Esto permite Editar & Continuar trabajando.

5

En realidad, xchg ax,ax es exactamente como MS desmonta "66 90". 66 es la anulación del tamaño del operando, por lo que supuestamente opera en ax en lugar de eax. Sin embargo, la CPU todavía lo ejecuta como un nop. El prefijo 66 se usa aquí para hacer que la instrucción tenga dos bytes de tamaño, generalmente con fines de alineación.

+0

también hay muchos otros NOP con diferentes tamaños y el compilador puede elegir el que mejor se adapte http://stackoverflow.com/ a/12564044/995714 –

Cuestiones relacionadas