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,0
excepto que es más corto que cmp
porque 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 eax
así 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 .