2010-10-24 25 views
8

Así que tengo el siguiente código de lenguaje ensamblador que necesito convertir a C. Estoy confundido en algunas líneas del código.Lenguaje ensamblador a C

Entiendo que este es un bucle for. He agregado mis comentarios en cada línea.

creo que el bucle for es la siguiente

for (int i = 1; i > 0; i << what?) { 
    //Calculate result 
} 

¿Cuál es la condición de prueba? ¿Y cómo lo cambio?

Mirando el código de ensamblaje, ¿qué hace la variable 'n'?

Este es Intel x86 por lo que el formato es fuente movl =, DEST

movl 8(%ebp), %esi  //Get x 
    movl 12(%ebp), %ebx //Get n 
    movl $-1, %edi   //This should be result 
    movl $1, %edx   //The i of the loop 
.L2: 
    movl %edx, %eax 
    andl %esi, %eax 
    xorl %eax, %edi  //result = result^(i & x) 
    movl %ebx, %ecx  //Why do we do this? As we never use $%ebx or %ecx again 
    sall %cl, %edx   //Where did %cl come from? 
    testl %edx, %edx  //Tests if i != what? - condition of the for loop 
    jne .L2    //Loop again 
    movl %edi, %eax  //Otherwise return result. 
+1

testl% edx,% edx comprueba si edx es 0. y luego jne - jump if not zero. –

+0

¿Qué líneas te confunden? En C, un bucle for es para (;;) {} –

+0

¿Por qué está convirtiendo el ASM heredado en C? –

Respuesta

14

sall %cl, %edx turnos% EDX dejados por %cl bits. (%cl, como referencia, es el byte bajo de %ecx). El siguiente testl prueba si ese cambio se ha reducido a cero% edx.

El jne se llama así porque a menudo se utiliza en el contexto de las comparaciones, que en ASM a menudo son solo sustracciones. Las banderas se establecerán según la diferencia; ZF se establecerá si los elementos son iguales (ya que x - x == 0). También se llama jnz en la sintaxis Intel; No estoy seguro si GNU también lo permite.

En conjunto, las tres instrucciones se traducen en i <<= n; if (i != 0) goto L2;. Eso más la etiqueta parece hacer un bucle for.

for (i = 1; i != 0; i <<= n) { result ^= i & x; } 

O, más correctamente (pero lograr el mismo objetivo), un bucle do ... while.

i = 1; 
do { result ^= i & x; i <<= n; } while (i != 0); 
+0

¡Gracias! Eso fue muy útil. – Catie

Cuestiones relacionadas