miércoles, 9 de mayo de 2012

Tarea Intro: Lenguaje ensamblador

Intro
El lenguaje ensamblador es un tipo de bajo nivel, ya que es la forma mas directa en la que nos podemos comunicar con el computador y cada una depende de su arquitectura.
En varias ocasiones nos preguntamos como un lenguaje lo entiende la computadora, la respuesta esta en los compiladores, ya que estos funcionan como intermediarios, viendo en otra forma, como un traductor, dependiendo de su instrucción este lo traducira a lenguaje ensamblador, para ser procesado en el procesador.

¿Algunas ventajas o porque saber/tener una idea de eso?
Una de las mayores ventajas viendolo en el ambito laboral, es que es muy bien pagada, ya que la mayoria de los programadores les resulta un dolor de cabeza, por lo que podemos decir que no cualquiera es un buen programador en esta área. Otra de las ventajas es como ya mencionado, la forma mas natural de comunicación entre nosotros y el computador, por lo que hacer un programa en ensamblador, será en los mayores casos, mucho mas eficáz, no requerirá tanto procesamiento por ser directo al momento de jugar con los registros o indicar el tamaño que ocupara estos.


Algo mas Geek...
Si nos resulta interesante esta área, una de las utilidades que podemos hacer es crear nuestros propios controladores, ya que para un dispositivo hardware pueda comicarse con una computadora, es necesario tener drivers(comunicación). Así que nosotros podríamos programar la comunicación de un control remoto para que prendiera en lugar de una tele, prendiera la computadora, un foto, entre otros.

Tarea:
Para esta tarea, mi idea fue hacer la función random donde te diera un numero del 0 al 10. Haciendolo primero en lenguaje c, despues lo traduje en ensamblador por medio de un comando y despues optimizando este, ya que te crea algunos códigos de línea basura.

C
#include 
#include 
#include 

main ()
{
  srand ( time(NULL) );
  printf ("Numero aleatorio: %d\n", rand() % 10);
  return 0;
}

Traducción:
 .file "r2.c"
 .section .rodata
.LC0:
 .string "Numero aleatorio: %d\n"
 .text
.globl main
 .type main, @function
main:
 pushl %ebp
 movl %esp, %ebp
 andl $-16, %esp
 subl $16, %esp
 movl $0, (%esp)
 call time
 movl %eax, (%esp)
 call srand
 call rand
 movl %eax, %ecx
 movl $1717986919, %edx
 movl %ecx, %eax
 imull %edx
 sarl $2, %edx
 movl %ecx, %eax
 sarl $31, %eax
 subl %eax, %edx
 movl %edx, %eax
 sall $2, %eax
 addl %edx, %eax
 addl %eax, %eax
 movl %ecx, %edx
 subl %eax, %edx
 movl $.LC0, %eax
 movl %edx, 4(%esp)
 movl %eax, (%esp)
 call printf
 movl $0, %eax
 leave
 ret
 .size main, .-main
 .ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
 .section .note.GNU-stack,"",@progbits

Optimización
.LC0:    ;Etiqueta
 .string "Numero aleatorio: %d\n" ;Indicamos que la etiqueta contedra un string
.globl main     ;Declaramos main como global
 .type main, @function   ;Declaramos main como function
main:      ;Empezamos main
 pushl %ebp    ;Prologo
 movl %esp, %ebp   ;Creamos el nuevo stack
 andl $-16, %esp   ;Alineamos la pila
 subl $16, %esp   ;Reservamos 16 bytes
 movl $0, (%esp)   ;Inicializamos con 0 el registro
 call time    ;Llamamos a la funcion time
 movl %eax, (%esp)   ;Movemos el registro
 call srand    ;Llamos a la funcion srand
 call rand    ;Llamos a la funcion rand
 movl %eax, %ecx   ;Movemos el registro
 movl $1717986919, %edx  ;Movemos el registro ###bytes, ya que es nuestros espacio del rand
 imull %edx    ;Multiplicamos el entero del registro
 sarl $2, %edx   ;Recorremos dos bytes del registro
 movl %ecx, %eax   ;Movemos el registro
 sarl $31, %eax   ;Recorremos el registro 31 bytes
 subl %eax, %edx   ;Hacemos la resta entre los resgritros
 movl %edx, %eax   ;Movemos el registro 
 sall $2, %eax   ;Acarreamos dos lugares el registro
 addl %edx, %eax   ;Hacemos la suma de los registros del acarreado con el qu restamos anteriormente
 addl %eax, %eax   ;Hacemos la suma del nuevo elemento
 movl %ecx, %edx   ;Movemos registro
 subl %eax, %edx   ;Hacemos la resta de los registros
 movl %edx, 4(%esp)   ;Movemos el restro a la cima para su impresion
 movl $.LC0, (%esp)   ;Mandamos llamar la etiqueta
 call printf    ;Imprimimos
 movl $0, %eax   ;Hacemos el return del registro 
 leave     ;Liberamos las variables
 ret

Resultado:



Bibliografía:
http://www.cs.mun.ca/~rod/winter2004/cs3724/notes/asm.html
http://programminggroundup.blogspot.mx/2007/01/appendix-b-common-x86-instructions.html
http://www.cs.virginia.edu/~evans/cs216/guides/x86.html

1 comentario: