assembler and assembly x86 att

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 .