Conociendo el lenguaje ensamblador

Imagina que vives en una época donde para comunicarnos sólo existen dos palabras, “SI” y “NO”, entonces si tu dices

“SI SI SI NO SI NO SI NO”

lo que tendría que interpretar la persona con la que estás hablando es “Hola, ¿cómo estás?”, suena interesante, pero algo complicado, ¿no crees?, un día llegas a tu casa y dices:

“SI NO SI NO SI SI SI SI”

pensando que lo que dijiste fue: “Cierra la llave del gas”, pero la otra persona lo que entendió fue:

“SI NO NO NO SI SI SI SI”

lo que quiere decir: “Enciende la estufa”, creo que en este punto es bastante obvio que va a haber un problema grave en tu casa.

Si te das cuenta el simple hecho de haber cambiado un SI por un NO hizo que el mensaje se modificara bastante. Entonces llegó alguien y dijo: “Esto es muy complicado, vamos a crear frases”, entonces para comunicarte se crearon algunas frases ya establecidas, por ejemplo: “Hola”, “Ve a la tienda”, “Haz tu tarea”, etc., esto facilitaría demasiado la comunicación con otras personas, algo similar es lo que sucede con el lenguaje ensamblador, lo que realiza es “convertir” diferentes instrucciones a código máquina (compuesto únicamente por “1” y “0”).

Los microcontroladores utilizan un lenguaje digital, compuesto únicamente por “1” y “0”, y están llenos de registros que se pueden entender como “espacios” dentro del microcontrolador que sirven para algo en particular o que pueden utilizarse para propósitos generales. Por ejemplo, en algún registro tendremos la información de un puerto en particular, como PORTB, con PORTB podemos escribir o leer sus valores para tener comunicación con el mundo real, existen otros registros como TRISB, el cual se utiliza para configurar si el puerto B será entrada o salida, por lo tanto es un registro de configuración.

Las instrucciones de lenguaje ensamblador van a modificar los valores de los registros para lograr crear las aplicaciones y los códigos deseados. Estas instrucciones se pueden dividir en:

  • Operaciones orientadas a bytes
MOVWF TRISB     ;Mueve el valor del registro W al registro TRISB
  • Operaciones orientadas a bits
bsf	    INTCON,7      ;Pone en "1" el bit 7 del registro INTCON
  • Operaciones con literales
movlw    0x00      ;Mueve el valor literal 0x00 al registro W
  • Operaciones de control
goto BUCLE      ;Va a la etiqueta "BUCLE"

Tanto el PIC 18F4550 (Miuva) como el 18F87J50 (Miuva Pro) cuentan con un total de 75 instrucciones. Estas instrucciones puedes encontrarlas en las hojas de datos de los PICs, por ejemplo, en la del 18F4550 puedes encontrar en la página 316 lo siguiente:

Imagen1. Instrucciones del PIC 18F4550

 

Puedes observar que la estructura de las instrucciones es similar, y tienen algunas letras (f, d, a) a un lado de la instrucción, esto quiere decir:

  • f: El registro con el que se está trabajando
  • d: El destino del resultador; si es 0 el resultado se guarda en el registro W, si es 1 se guarda en el registro f
  • a: La memoria a la que se accesó

Similarmente esta explicado en la hoja de datos para el caso de los parámetros de las instrucciones orientadas a bits, con literales o de control.

También podemos notar que muchas veces se hace mención del registro W, éste es el registro de trabajo (Work), es un registro que se utiliza como un operando para la ALU y que incluso puede almacenar el resultado, o visto de otra forma, es un registro dónde podremos guardar información temporalmente para usarla en una gran cantidad de instrucciones.

Por ejemplo para escribir un 0x00 (literal) en el registro TRISB, podemos mover el valor 0x00 al registro W y posteriormente mover lo que hay en el registro W al registro TRISB:

MOVLW     0x00     ;Movemos el 0x00 al registro de trabajo
MOVWF     TRISB    ;Movemos el contenido de W al registro TRISB

Ahora tal vez puedas preguntarte, ¿para qué sirve el lenguaje ensamblador si puedo usar C?, a pesar de que el lenguaje C ofrece muchas ventajas, entre ellas un entendimiento más fácil y legible a la hora de programar y una menor cantidad de líneas de código, por ejemplo, para hacer parpadear un led en C:

#include    <18F87J50.h>
#fuses      HSPLL, NOWDT, NOPROTECT, NODEBUG, PLL2
#use        delay (clock=8M)

void main(){
   output_high(PIN_E1);
   delay_ms(200);
   output_low(PIN_E1);
}

Mientras que en ensamblador son necesarias las siguientes líneas:

LIST    P = 18F4550	;PIC a utilizar
INCLUDE <P18F4550.INC>

CONFIG  FOSC = HS   
CONFIG  PWRT = ON
CONFIG  BOR = OFF
CONFIG  WDT = OFF
CONFIG  MCLRE = ON
CONFIG  PBADEN = OFF
CONFIG  LVP = OFF
CONFIG  DEBUG = OFF
CONFIG  XINST = OFF

CBLOCK  0x000
    Ret1	;Variables para los retardos de 1 segundo
    Ret2
    Ret3
ENDC

ORG 0x0000
GOTO START

org 0x30

START

    movlw   0x0F    
    movwf   ADCON1  ;Configuración de entradas digitales
    movlw   0x00
    movwf   TRISE   ;Configura PUERTO E como salida
    movlw   0x07   
    movwf   PORTE   ;Valores iniciales del puerto E

INICIO

Retardo1sON
    movlw   .255    ;Cargamos los valores de los retardos a las constantes
    movwf   Ret1    ;correspondientes
    movlw   .255
    movwf   Ret2
    movlw   .11
    movwf   Ret3
Ret1sON
    decfsz  Ret1, F ;Decrementa el valor de Ret1 y salta si es igual a 0
    bra	    Ret1sON ;Saltamos a Ret1sON
    decfsz  Ret2, F ;Decremente el valor de Ret2 y salta si es igual a 0
    bra	    Ret1sON ;Saltamos a Ret1sON
    decfsz  Ret3, F ;Decremente el valor de Ret3 y salta si es igual a 0
    bra	    Ret1sON ;Saltamos a Ret1sON
    movlw   0x06    
    movwf   PORTE	;Encendemos el led ubicado en E0

Retardo1sOFF
    movlw   .255
    movwf   Ret1
    movlw   .255
    movwf   Ret2
    movlw   .11
    movwf   Ret3
Ret1sOFF
    decfsz  Ret1, F
    bra	    Ret1sOFF
    decfsz  Ret2, F
    bra	    Ret1sOFF
    decfsz  Ret3, F
    bra	    Ret1sOFF
    movlw   0x07
    movwf   PORTE   ;Apaga el LED

    goto    INICIO	;Regresa al INICIO

    END             ;Fin de Programa

Al utilizar un lenguaje como C, estamos limitados a las funciones ya existentes del compilador, por lo cual a veces se realizarán tareas que no necesitaremos, lo cual nos hará perder tiempo o bajar el rendimiento de nuestro microcontrolador, entonces cuando necesitemos aplicaciones que requieren ser optimizadas podemos apoyarnos del lenguaje ensamblador, pero como podrás notar, para esto será necesario conocer más a fondo el funcionamiento y la estructura del microcontrolador con el cual estaremos trabajando.

Al trabajar más directamente con el hardware el lenguaje ensamblador se conoce como un lenguaje de bajo nivel mientras que C se conoce como un lenguaje de alto nivel.

Menú