Posteriormete explicare un programa un poco mas complejo.
Es el clásico ordenamiento de números por el método burbuja.
Primero el código original en C:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
main (){ | |
int N,i,pasadas,almacena; | |
printf("Metodo Burbuja"); | |
int A[10]={6,30,7,1,43,12,2,10,11,5}; | |
printf("\nEl arreglo en desorden es"); | |
for(i=0;i<10;i++){ | |
printf(" %d ", A[i]); | |
} | |
for(pasadas=1;pasadas<N;pasadas++){ | |
for(i=0;i<10-1;i++){ | |
if(A[i]>A[i+1]){ | |
almacena=A[i]; | |
A[i]=A[i+1]; | |
A[i+1]=almacena; | |
} | |
} | |
} | |
printf("\nEl arreglo ordenado es: "); | |
for(i=0;i<10;i++){ | |
printf(" %d ", A[i]); | |
} | |
printf("\n"); | |
return 0; | |
} |
gcc –S burbuja.c
Ahora aqui ya tenemos nuestro código .s lo mostramos y lo comentarizamos
para entenderlo un poco más.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.file "burbuja.c" // nombre del archivo | |
.section .rodata // y creacion de asembly | |
.LC0: // primera seccion que guarda | |
.string "Metodo Burbuja" // una cadena de caracteres | |
.LC1: // otra seccion que | |
.string "\nEl arreglo" // tambien guarda una cadena | |
.LC2: // En esta seccion se guarda una | |
.string " %d " // cadena, es para tomar un numero | |
.LC3: // En esta parte se guarda un cada | |
.string "\nEl arreglo ordenado es: " // que es la segunda que se muestra | |
.text // y se señala que es un texto | |
.globl main // se declara main tipo global | |
.type main, @function // se dice main como una funcion | |
main: // se inicia el programa con un main | |
pushl %ebp // se reserva espacion en memoria | |
movl %esp, %ebp // mueve esp para ebp | |
andl $-16, %esp // un tamañoo de 16 bytes | |
subl $80, %esp // para subtract desde el destinatario se 80 bytes | |
movl $.LC0, %eax // mueve la parte de LCO en la pila para imprimirla | |
movl %eax, (%esp) // se reserva un espacio | |
call printf // y luego se imprime el mensaje | |
movl $6, 24(%esp) // apartir de aqui se va llenando | |
movl $30, 28(%esp) // todo el arreglo que declaramos en C | |
movl $7, 32(%esp) // y para cada elemento se va reservando | |
movl $1, 36(%esp) // un espacio en memoria | |
movl $43, 40(%esp) | |
movl $12, 44(%esp) | |
movl $2, 48(%esp) | |
movl $10, 52(%esp) | |
movl $11, 56(%esp) | |
movl $5, 60(%esp) // aqui terminamos con el arreglo | |
movl $.LC1, %eax // ahora se mueve y se manda llamar | |
movl %eax, (%esp) // la siguiente cadena | |
call printf // y se imprime en pantalla | |
movl $0, 76(%esp) // movemos un 0 en el espacio 76 | |
jmp .L2 // brincamos a la instruccion .L2 | |
.L3: | |
movl 76(%esp), %eax // movemos el valor que esta en 76 | |
movl 24(%esp,%eax,4), %edx // movemos aqui el valor que esta en 24 que es el 6 | |
movl $.LC2, %eax // leemos que es un numero con el .LC2 %d | |
movl %edx, 4(%esp) // movemos un espacio de 4 bytes para los | |
movl %eax, (%esp) // numeros | |
call printf // lo impimimos | |
addl $1, 76(%esp) // agregamos un 1 a 76 para que siga con el sig numero | |
.L2: | |
cmpl $9, 76(%esp) // hacemos una comparacion del valor que esta en 9 | |
jle .L3 // si es menor vamos a .L3 | |
movl $1, 72(%esp) // movemos valor que esta en 1 y ponemos el de 72 | |
jmp .L4 // brincamos a .L4 | |
.L8: | |
movl $0, 76(%esp) // aqui ponemos un 0 en el espacio 76 | |
jmp .L5 // saltamos a la seccion .L5 | |
.L7: | |
movl 76(%esp), %eax // en esta parte movemos al espacio en 76 | |
movl 24(%esp,%eax,4), %edx // luego movemos al primer numero | |
movl 76(%esp), %eax // comprobamos con el de 76 | |
addl $1, %eax // agregamos uno para aumentar | |
movl 24(%esp,%eax,4), %eax // movemos al espacio en 24 para un numero de 4 bytes | |
cmpl %eax, %edx // coparamos | |
jle .L6 // si es menor o igual vamos al .L6 | |
movl 76(%esp), %eax // nos movemos al 76 otra ves aumentado uno | |
movl 24(%esp,%eax,4), %eax // comprobamos otra ves al 24 | |
movl %eax, 64(%esp) // nos movemos al espacio en 64 | |
movl 76(%esp), %eax // de nuevo al 76 para checar | |
addl $1, %eax // agregamos un uno | |
movl 24(%esp,%eax,4), %edx // nos movemos al 24 para volver a checar | |
movl 76(%esp), %eax // y comprobamos el 76 | |
movl %edx, 24(%esp,%eax,4) // separamos 4 bytes para el numero que esta en 24 | |
movl 76(%esp), %eax // checamos de nuevo el 76 | |
leal 1(%eax), %edx // coloca 1 en el primer operador | |
movl 64(%esp), %eax // nos movemos al 64 para seguir con el ciclo | |
movl %eax, 24(%esp,%edx,4) // y separamos los 4 bytes para los numeros | |
.L6: | |
addl $1, 76(%esp) // como es menor, le agregamos uno | |
.L5: | |
cmpl $8, 76(%esp) //hacemos comparacion del espacio 8 y el 76 | |
jle .L7 // si es menor o igual vamos al .L7 | |
addl $1, 72(%esp) // agregamos un 1 al espacio en 76 | |
.L4: | |
movl 72(%esp), %eax // movemos el espacio que hay en 72 | |
cmpl 68(%esp), %eax // comprobamos el espacio de 68 | |
jl .L8 // brincar cuando es menor al L8 | |
movl $.LC3, %eax // mover la cadena que hay en .LC3 | |
movl %eax, (%esp) // crear espacio | |
call printf // imprimimos el mensaje | |
movl $0, 76(%esp) // nos movemos otra ves al espacio 0 | |
jmp .L9 // saltamos a la instruccion L9 | |
.L10: | |
movl 76(%esp), %eax // nos movemos al espacio 76 | |
movl 24(%esp,%eax,4), %edx // movemos al 26 que es donde esta el primer numero | |
movl $.LC2, %eax // llamamos al .LC2 para leer el numero | |
movl %edx, 4(%esp) // ocupamos 4 bytes para el | |
movl %eax, (%esp) // espacio de cada numero | |
call printf // y lo imprimimos | |
addl $1, 76(%esp) // le agregamos un 1 al 76 para que haga el ciclo | |
.L9: | |
cmpl $9, 76(%esp) // hacemos una comprobacion entre el 9 y el 76 en memoria | |
jle .L10 // saltamos cuando es menor o igual a la parte L10 | |
movl $10, (%esp) // nos movemos al espacio 10 | |
call putchar // llamamos al char | |
movl $0, %eax // nos movemos al espacio en 0 | |
leave // libera las variables locales | |
ret // equivalente al return y fin | |
.size main, .-main // expresion de tamaño de main | |
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2" //version del gcc | |
.section .note.GNU-stack,"",@progbits // seccion generada por el gcc |
Por ultimo, optimizamos el programa quitando lineas de código para su mejoramiento y rendimiento:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.LC1: | |
.string "\nEl arreglo en desorden es: " | |
.LC2: | |
.string " %d " | |
.LC3: | |
.string "\nEl arreglo en orden es: " | |
.text | |
.globl main | |
main: | |
pushl %ebp | |
movl %esp, %ebp | |
andl $-16, %esp | |
subl $80, %esp | |
movl %eax, (%esp) | |
call printf | |
movl $6, 24(%esp) | |
movl $30, 28(%esp) | |
movl $7, 32(%esp) | |
movl $1, 36(%esp) | |
movl $43, 40(%esp) | |
movl $12, 44(%esp) | |
movl $2, 48(%esp) | |
movl $10, 52(%esp) | |
movl $11, 56(%esp) | |
movl $5, 60(%esp) | |
movl $.LC1, %eax | |
movl %eax, (%esp) | |
call printf | |
movl $0, 76(%esp) | |
jmp .L2 | |
.L3: | |
movl 76(%esp), %eax | |
movl 24(%esp,%eax,4), %edx | |
movl $.LC2, %eax | |
movl %edx, 4(%esp) | |
movl %eax, (%esp) | |
call printf | |
addl $1, 76(%esp) | |
.L2: | |
cmpl $9, 76(%esp) | |
jle .L3 | |
movl $1, 72(%esp) | |
jmp .L4 | |
.L8: | |
movl $0, 76(%esp) | |
jmp .L5 | |
.L7: | |
movl 76(%esp), %eax | |
movl 24(%esp,%eax,4), %edx | |
movl 76(%esp), %eax | |
addl $1, %eax | |
movl 24(%esp,%eax,4), %eax | |
cmpl %eax, %edx | |
jle .L6 | |
movl 76(%esp), %eax | |
movl 24(%esp,%eax,4), %eax | |
movl %eax, 64(%esp) | |
movl 76(%esp), %eax | |
addl $1, %eax | |
movl 24(%esp,%eax,4), %edx | |
movl 76(%esp), %eax | |
movl %edx, 24(%esp,%eax,4) | |
movl 76(%esp), %eax | |
leal 1(%eax), %edx | |
movl 64(%esp), %eax | |
movl %eax, 24(%esp,%edx,4) | |
.L6: | |
addl $1, 76(%esp) | |
.L5: | |
cmpl $8, 76(%esp) | |
jle .L7 | |
addl $1, 72(%esp) | |
.L4: | |
movl 72(%esp), %eax | |
cmpl 68(%esp), %eax | |
jl .L8 | |
movl $.LC3, %eax | |
movl %eax, (%esp) | |
call printf | |
movl $0, 76(%esp) | |
jmp .L9 | |
.L10: | |
movl 76(%esp), %eax | |
movl 24(%esp,%eax,4), %edx | |
movl $.LC2, %eax | |
movl %edx, 4(%esp) | |
movl %eax, (%esp) | |
call printf | |
addl $1, 76(%esp) | |
.L9: | |
cmpl $9, 76(%esp) | |
jle .L10 | |
movl $10, (%esp) | |
call putchar | |
movl $0, %eax |
Aqui la presentación que se expondra en clase:
Bibliografía para poder comentarizar el código:
http://www.cs.virginia.edu/~evans/cs216/guides/x86.html
http://zsmith.co/intel/intel.html
No hay comentarios:
Publicar un comentario