martes, 28 de febrero de 2012

Tarea Intro 1

Para comenzar realize un programa sencillo, un hola mundo cambiandolo para probar.


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:

#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;
}
view raw gistfile1.c hosted with ❤ by GitHub
Despues de cambiarlo a Asembly por medio de la instrucción:

gcc –S burbuja.c

Ahora aqui ya tenemos nuestro código .s lo mostramos y lo comentarizamos
para entenderlo un poco más.

.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
view raw gistfile1.asm hosted with ❤ by GitHub

Por ultimo, optimizamos el programa quitando lineas de código para su mejoramiento y rendimiento:

.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
view raw gistfile1.asm hosted with ❤ by GitHub

Aqui la presentación que se expondra en clase:
Tarea intro
View more presentations from dani.

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