Saltar al contenido

En x86, ¿cuál es la diferencia entre “test eax,eax” y “cmp eax,0”?

Este dilema se puede abordar de diversas maneras, pero en este caso te mostramos la resolución más completa en nuestra opinión.

Solución:

Como Zang MingJie ya ha dicho en un comentario, test eax,eax es casi identico a cmp eax,0excepto que es más corto que cmpporque con cmp tienes que suministrar 0 como argumento. Tenga en cuenta que los ahorros no son muy grandes, porque el segundo operando se extiende con signo para que coincida con el tamaño del primer operando, por lo que no necesariamente se necesitan 4 bytes completos para representar ese cero.

Ahora, lo que estás preguntando es si hay alguna otra diferencia. Esta es una pregunta razonable, porque cmp es una operación aritmética, (realiza una resta y descarta el resultado), mientras que test es una operación lógica (realiza un AND bit a bit y descarta el resultado), por lo que uno podría sospechar razonablemente que pueden modificar el Flags registrarse de manera diferente.

Resulta que ambas instrucciones modifican el Flags registrarse en un casi moda idéntica. Ambas instrucciones modifican los bits OF SF ZF AF PF y CF del registro de banderas. los test instrucción siempre borra OF y CF, pero eso es también lo que cmp contra cero lo hace. La única otra diferencia es que el cmp la instrucción establecerá correctamente el oscuro AF bandera, mientras que la test instrucción deja el contenido de esa bandera sin definir. Pero en el caso de cmp eax,0 el AF siempre se borrará independientemente del valor de eaxasí que no hay nada que puedas aprender de un cmp eax,0 que no aprenderías de un test eax,eax.

Por lo tanto, concluiría que no hay ninguna situación en la que test eax,eax te dará algo que cmp eax,0 no lo hará, ni viceversa. Las dos instrucciones parecen ser completamente intercambiables para cualquier propósito práctico o incluso no tan práctico, excepto para guardar uno o dos bytes del código de instrucción.

Utilizando test eax,eax en lugar de cmp eax,0 demuestra que conoce su montaje. También muestra que prefiere una instrucción un poco críptica y ligeramente mejor que una instrucción sencilla y comprensible. Este es el tipo de cosa que tiende a ganar puntos de bonificación de otros geeks, pero no ha tenido ninguna utilidad práctica en el mundo real en las últimas dos décadas más o menos.

Diferencia (Teórica)

Como se indicó anteriormente en el comentario y la respuesta aceptada, también que estas instrucciones son casi idéntico cuando se usa de esta manera, pero entonces, ¿por qué hay dos instrucciones en el conjunto de instrucciones si son iguales?

Porque son diferentes si se usan con diferentes operandos.
El hecho de que test same,same funciona como una comparación contra cero es solo una consecuencia conveniente de cómo funcionan el complemento a 2 y FLAGS, lo que lo convierte en una optimización de mirilla útil.

La instrucción TEST usa la lógica AND en los pares de bits de arg0 y arg1 y puede verificar si un bit específico está configurado o no, luego FLAGS se configura en consecuencia. (Con el resultado entero descartado). Al igual que cmp establece FLAGS de una resta mientras descarta el resultado entero.

Operación (PRUEBA)

HTML excepto del manual en PDF vol.2 de Intel

TEMP ← SRC1 **AND** SRC2;
SF ← MSB(TEMP);
IF TEMP=0
    THEN ZF ← 1;
    ELSE ZF ← 0;
FI:

PF ← BitwiseXNOR(TEMP[0:7]);
CF ← 0;
OF ← 0;
(* AF is undefined *)

Banderas afectadas

Los indicadores OF y CF se establecen en 0. Los indicadores SF, ZF y PF se establecen según el resultado (consulte la sección “Operación” anterior). El estado de la bandera AF no está definido.

(La operación TEST establece los indicadores CF y OF en cero. SF se establece en el bit más significativo del resultado de AND. Si el resultado es 0, ZF se establece en 1; de lo contrario, se establece en 0).


Tiempo La instrucción CMP usa la instrucción SUB y resta arg1 de arg0 y establecerá CF (Bandera de acarreo) y ZF (Bandera cero) según los argumentos dados a la instrucción CMP, si ambos son iguales (arg1==arg0) entonces es obvio que el resultado será cero y ZF se establecerá en 1 y si arg0 > arg1 entonces no se establecerá ninguna bandera (sigue siendo 0 para ZF y CF) y si arg0 < arg1 entonces ZF permanecerá en 0 ya que no son iguales pero se establecerá CF.

Operación (CMP)

temp ← SRC1 − SignExtend(SRC2); 
ModifyStatusFlags; 
   (* Modify status flags in  the same manner as the SUB instruction*)

Banderas afectadas

Los indicadores CF, OF, SF, ZF, AF y PF se establecen según el resultado.

Referencia de: assembly_language_for_x86_processors.pdf

Acuérdate de que puedes agregar una reseña .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *