El punto de prueba %eax % eax [duplicado]


Posible Duplicado:
x86 Assembly - 'testl' eax contra eax?

Soy muy, muy nuevo en la programación en lenguaje ensamblador, y actualmente estoy tratando de leer el lenguaje ensamblador generado a partir de un binario. He corrido a través de

 test   %eax,%eax

O test %rdi, %rdi, etc. sucesivamente. Estoy muy confundido en cuanto a lo que esto hace. ¿No son los mismos valores en %eax, %eax? ¿Qué está probando? Leí en alguna parte que está haciendo la operación AND.....pero ya que son los el mismo valor, ¿no devolvería %eax?

Lo siguiente es solo un ejemplo donde encontré este uso:

   400e6e:       85 c0                   test   %eax,%eax
   400e70:       74 05                   je     400e77 <phase_1+0x23>

Pensé que je 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 en la programación en general, así que apreciaría mucho si alguien pudiera explicarme esto. ¡Gracias!

Author: Michael Petch, 2012-10-25

5 answers

CMP resta los operandos y establece las banderas. Es decir, establece la bandera cero si la diferencia es cero (los operandos son iguales).

TEST establece la bandera cero, ZF, cuando el resultado de la operación AND es cero. Si dos operandos son iguales, su bit a bit Y 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 [Saltar si es igual] pruebas la bandera cero y salta si la bandera está establecida. JE es un alias de JZ [Jump if Zero] por lo que el desensamblador no puede seleccionar uno basado en el opcode. JE se llama así porque la bandera cero se establece si los argumentos a CMP son iguales.

Así que,

TEST %eax, %eax
JE   400e77 <phase_1+0x23>

Salta si el %eax es cero.

 109
Author: John Dvorak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-25 19:00:43

Algunas instrucciones de x86 están diseñadas para dejar el contenido de los operandos (registros) tal como están y simplemente establecer/desajustar banderas internas específicas de la CPU como la bandera cero (ZF). Puede pensar en el ZF como una bandera booleana true/false que reside dentro de la CPU.

en este caso particular, la instrucción de PRUEBA realiza un AND lógico bitwise, descarta el resultado real y establece / desactiva el ZF de acuerdo con el resultado del and lógico: 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 observar el ZF para saltar / no saltar, por lo que usar TEST y JE juntos equivale a realizar un salto condicional basado en el valor de un registro específico:

ejemplo:

PRUEBA EAX, EAX
JE some_address

la CPU saltará a "some_address" si y solo si ZF = 1, en otras palabras si y solo si Y (EAX,EAX) = 0 que a su vez puede ocurrir si y solo si EAX = = 0

el código C equivalente ser:

if(eax == 0)
{
    goto some_address
}
 39
Author: Gianluca Ghettini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-06 14:17:40

Esto comprueba si EAX es cero. La instrucción test hace AND bitwise entre los argumentos, y si EAX contiene cero, el resultado fija el ZF, o ZeroFlag.

 9
Author: ppeterka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-25 08:53:39

test es un and no destructivo, no devuelve el resultado de la operación pero establece el registro de banderas en consecuencia. Para saber lo que realmente prueba para usted necesita comprobar las siguientes instrucciones. A menudo out se utiliza para comprobar un registro contra 0, posiblemente junto con un salto condicional jz.

 3
Author: Jens Björnhager,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-25 08:59:26

Tienes razón, que test "y"s los dos operandos. Pero el resultado se descarta, lo único que queda, y eso es lo importante, son las banderas. Se establecen y esa es la razón por la que se usa la instrucción test (y existe).

JE no salta cuando es igual (tiene el significado cuando la instrucción anterior era una comparación), lo que realmente hace, salta cuando se establece la bandera ZF. Y como es una de las banderas que se establece por 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) solo puedo recomendar un libro sobre la instrucción x86, por ejemplo, incluso cuando es realmente grande, la documentación de Intel es muy buena y precisa.

 2
Author: flolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-25 08:54:03