assembly - and - El punto de la prueba% eax% eax
gnu assembler (5)
Posible duplicado:
Asamblea x86 - ''testl'' eax contra eax?
Soy muy nuevo en programación en lenguaje ensamblador, y actualmente estoy tratando de leer el lenguaje ensamblador generado desde un binario. Me he encontrado
test %eax,%eax
o test %rdi, %rdi
, etc. Estoy muy confundido en cuanto a lo que hace esto. ¿No son los valores en %eax, %eax
iguales? ¿Qué está probando? Leí en alguna parte que está haciendo la operación AND
... pero dado que tienen el mismo valor, ¿no devolvería %eax
?
La siguiente es solo una instancia en la que encontré este uso:
400e6e: 85 c0 test %eax,%eax
400e70: 74 05 je 400e77 <phase_1+0x23>
Pensé que salta si los dos valores que se comparan son iguales ... bueno, porque %eax
está bien, en sí mismo, ¿en qué situación NO saltaríamos?
Soy un principiante de la programación en general, por lo que agradecería mucho si alguien pudiera explicarme esto. ¡Gracias!
Algunas instrucciones x86 están diseñadas para dejar el contenido de los operandos (registros) tal como están y simplemente configuran / desarman indicadores internos específicos de CPU como el indicador de cero (ZF). Puede pensar en ZF como un indicador booleano verdadero / falso que reside dentro de la CPU.
en este caso particular, la instrucción TEST realiza un AND lógico a nivel de bit, descarta el resultado real y establece / desactiva el ZF según el resultado de la lógica y: si el resultado es cero, establece ZF = 1; de lo contrario, establece ZF = 0.
Las instrucciones de salto condicional como JE están diseñadas para mirar la ZF para saltos / saltos, por lo que usar TEST y JE juntos es equivalente a realizar un salto condicional basado en el valor de un registro específico:
ejemplo:
TEST EAX, EAX
JE some_address
la CPU saltará a "some_address" si y solo si ZF = 1, en otras palabras, si y solo si AND (EAX, EAX) = 0 que a su vez puede ocurrir si y solo si EAX == 0
el código C equivalente es:
if(eax == 0)
{
goto some_address
}
Esto comprueba si EAX
es cero. La test
instrucción realiza AND
bit entre los argumentos, y si EAX
contiene cero, el resultado establece ZF o ZeroFlag.
Tienes razón, esa test
"y" s los dos operandos. Pero el resultado se descarta, lo único que queda, y esa es la parte importante, son las banderas. Están configurados y esa es la razón por la cual se usa (y existe) la instrucción de test
.
JE
salta no cuando es igual (tiene el significado cuando la instrucción anterior era una comparación), lo que realmente hace, salta cuando se establece el indicador ZF
. Y como es uno de los indicadores que se establece mediante test
, esta secuencia de instrucciones (prueba x, x; je ...) tiene el significado de que se salta cuando x es 0.
Para preguntas como esta (y para más detalles), puedo recomendar un libro sobre las instrucciones x86, por ejemplo, incluso cuando es muy grande, la documentación de Intel es muy buena y precisa.
CMP
resta los operandos y establece los indicadores. A saber, establece el indicador de cero si la diferencia es cero (los operandos son iguales).
TEST
establece el indicador de cero, ZF
, cuando el resultado de la operación AND es cero. Si dos operandos son iguales, su Y a nivel de bit es cero cuando ambos son cero. TEST
también establece el indicador de signo, SF
, cuando el bit más significativo se establece en el resultado, y el indicador de paridad, PF
, cuando el número de bits establecidos es par.
JE
[Jump if Equals] prueba el indicador de cero y salta si se establece el indicador. JE
es un alias de JZ
[Jump if Zero] por lo que el desensamblador no puede seleccionar uno basado en el código de operación. JE
se llama así porque el indicador de cero se establece si los argumentos para CMP
son iguales.
Asi que,
TEST %eax, %eax
JE 400e77 <phase_1+0x23>
salta si el %eax
es cero.
test
es destructiva and
no devuelve el resultado de la operación, pero establece que las banderas se registren en consecuencia. Para saber qué es lo que realmente prueba, debe verificar las siguientes instrucciones. A menudo se usa para verificar un registro contra 0, posiblemente junto con un salto condicional jz
.