sábado, 4 de abril de 2009

Jugando con ensamblador. Que mello!!

Cada que me siento tras una IDE o un editor de textos como emacs o vi, en mi cabeza se invoca la voz de mi amiga Argelia que le reclama a su novio y a mi: Estas como medio obcesionado con la programación. Y como decirles que es mentira. 

Normalmente me dedico a programar en java, c, cuando se requiere en sql estandar y de vez en cuando en algo mas como visual o C#, pero no son lenguajes que me llamen la atención. Pero ahora me ha tocado programar en un viejo amigo complemento de C, si, ensamblador, o como le llamamos: Empalador (Pa' los cuates).

Así que me puse a recordar el set de instrucciones para la serie 8086 (i386) de intel. Pero oh sorpresa que me di, pues el micro que usamos es uno viejito, pero lindo. Me refiero al 8051, y por suerte su set de instrucciones es mas simple, pero mas rarito que el complejo set del i386. Pero ya te tome modo y este es el RC1 para uno de mis proyectos. 

Con ustedes, el código fuente!!! Aplausos, señores!

Este es un programa que manda por el puerto 1 numeros del 1 al F hexadesimal y hace dos sumas. Usa una tabla en apuntadores. 

clr A;
clr C;

mov DPTR, #Tabla ;
mov r3, #0 ;
mov r4, #02 ;
mov 20h, #0Fh ;
mov 30h, #05h ;
mov 31h, #09h ;
mov 32h, #03h ;
 
 ;; led's test
acall test ;
NOP ;
acall separador ;

 ;; Suma

mov A, 30h ;
movc A, @A+DPTR ;
mov P1, A ;
acall tiempito ;
mov A, 32h ;
movc A, @A+DPTR ;
mov P1, A ;
acall tiempito ;
 
 ;; separador de suma
 
acall separador ;

mov A, 30h ;
add A, 32h ;
movc A, @A+DPTR ;
mov P1, A ;
acall Tiempito ;

acall separador ;

 ;; Suma

mov A, 31h ;
movc A, @A+DPTR ;
mov P1, A ;
acall tiempito ;
mov A, 30h ;
movc A, @A+DPTR ;
acall tiempito ;

 ;; Sepaarador de suma
acall separador ;

mov A, 31h ;
add A, 30h ;
movc A, @A+DPTR ;
mov P1, A ;
acall tiempito ;


 ;; tabla
Tabla:
DB 11000000B; 0
DB 11111001B; 1
DB 10100100B; 2
DB 10110000B; 3
DB 10011001B; 4
DB 10010010B; 5
DB 10000010B; 6
DB 11111000B; 7
DB 10000000B; 8
DB 10010000B; 9
DB 10001000B; a
DB 10000011B; b
DB 11000110B; c
DB 10100001B; d
DB 10000110B; e
DB 10001110B; f

 ;; Rutina de retardo

tiempito:
 mov 90h, A;
 mov r0, #02;
 in1: mov r1, #040h;
 in2: mov r2, #090h;

 wait: djnz r2, wait;
  djnz r1, in2;
  djnz r0, in1;
  ret;
 
 ;; Rutina del test

test: mov A, 20h ;
 movc A, @A+DPTR ;
 mov P1, A ;
 acall tiempito;
 mov A, 20h ;
decr: subb A, #01h ;
 mov 21h, A ;
 movc A, @A+DPTR ;
 mov P1, A ;
 acall tiempito ;
 mov A, 21h ;
 jnz decr ;
 ret ;

 ;;Rutina de separador.

separador:
 mov A, #0B6h ;
 mov P1, A ;
 acall tiempito ;
 ret