Sunteți pe pagina 1din 6

Directivas del ensamblador

Las directivas no son instrucciones del microcontrolador, son indicaciones que se le dan al ensamblador para controlar algunos aspectos del ensamblado del cdigo. Todas las directivas se detallan en el manual respectivo de los tantos que se instalan junto con el paquete MPLAB. Como con los mnemnicos de instrucciones, al ensamblador le da igual si las directivas estn en maysculas o en minsculas. Aqu presentaremos las que suelen ser las ms habituales. Ya vimos en accin a muchas de ellas y las restantes las empezaremos a usar en adelante.

Directiva list Directiva processor Directiva include Directivas __config y __fuses Directiva equ Directivas cblock y endc Directiva org Directiva end Directiva banksel Directiva #define Directiva $ Directiva dt Directiva errorlevel Directiva messg Directivas if, ifdef, ifndef, else y endif

La directiva list
Es una directiva para listar una serie de opciones de ensamblado de diversa ndole. Los parmetros listados se separan por comas. Por ejemplo, siguiente directiva

list p = PIC16F84A, r = dec, b = 8, f = INHX8M


tiene cuatro parametros, cuyo significado es:

p: establece el Procesador destino (PICmicro). Esto ser equivalente a la directiva processor. r: establece el sistema de numeracin a usar por defecto. Como se vio al inicio, el formato de los nmeros se suele especificar por un prefijo: 0x para hexadecimal, . para decimal, etc. En caso de no especificar nada, el nmero ser considerado en el formato sealado por r. En el ejemplo, es obvio que se indica decimal. El valor por defecto es hex (hexadecimal). Esto es equivalente a la directiva radix. b: establece la cantidad de espacios en blanco que sern insertados en lugar de cada tabulacin del archivo *.lst. ste es un archivo secundario de los tantos que genera el ensamblador. De cualquier forma, ms adelante veremos para que puede servir. f: establece el Formato del archivo hexadecimal de salida. las opciones disponibles son INHX8M, INHX8S e INHX32. La primera es el valor por defecto.

Adems de los citados en este ejemplo hay muchos ms parmetros que se pueden incluir con la directiva list. Lo curioso es que ninguno puede ser necesario, es decir, todos se pueden indicar de otra forma, ya sea desde el entorno del ensamblador MPASM, del mismo MPLAB o mediante otra directiva. Mas aun, ni siquiera suele ser necesario mover las configuraciones por defecto. Es una costumbre poner list con al menos el parametro p = indicando el procesador. Para este propsito sera ms prctivo e intuitivo usar la directiva processor, descrita continuacin, que tiene el mismo objetivo.

La directiva processor
Es una directiva para establecer el PICmicro para el que se ensamblar el cdigo fuente. Es equivalente a poner la directiva list con el parmetro p. Con esta directiva el ensamblador sabr qu tipo de instrucciones utilizar, aunque en ese sentido hay muy pocas variaciones entre uno y otro procesador. No obstante, resalto que poner estas directivas solo suele ser necesario cuando se llame al ensamblador desde una lnea de comandos, por ejemplo, cuando se ensambla el programa desde Proteus VSM. No hacen falta, por ejemplo, cuando se cuando se contruye el proyecto desde MPLAB IDE.

processor PIC16F84A

La directiva include
Es la directiva para incluir como parte del programa el archivo que se indica. La inclusin se realiza como si se aplicara un copiar pegar del contenido entero del archivo incluido en el lugar donde aparece la directiva.

Esta directiva debe aparecer en todos los programas de ensamblador al menos para incluir el archivo de dispositivo del PIC usado, como muestra el siguiente ejemplo. Estos archivos se hallan en la carpeta de instalacin del ensamblador MPASM, que a su vez se instala con MPLAB IDE, norlmalmente C:\Microchip\MPASM Suite. Solo ponemos la directiva y el ensamblador sabr dnde buscarlo.

include <P16F84A.inc> ; incluir archivo P16F84A.inc


Include tambin se usa para incorporar archivos de otros tipos, como libreras de cdigos. Es una convencin usar los signos < > para referirse a los archivos estndar y los signos para referirse a los archivos de usuario. Incluso pueden ignorarse dichos signos asi como poner por delante el signo #. Queda claro que no se imponen las restricciones que tiene esta directiva en el lenguaje C.

include "lcd.asm"

; incluir archivo lcd.asm

#include P16F877A.inc ; incluir archivo P16F877A.inc Las directivas __config y __fuses


__config es ms popular que __fuses a pesar de tener el mismo propsito (por lo menos en los PIC16) y de que el nombre de la segunda parecera ms ilustrativo. Son directivas para establecer los Fuses de Configuracin. Los fuses tambin se pueden establecer en el entorno del programa grabador (WinPic800, por ejemplo), pero es recomedable hacerlo mediante esta directiva para que formen parte del archivo *.hex resultante. Recuerda que el PIC16F84A tiene 4 fuses y los PIC16F87xA tienen 9. Todos los hemos estudiado antes. Los fuses se ponen con un nmero o a travs de mscaras que las representan. Estas mscaras se encuentran en el archivo de dipositivo del PICmicro. Por ejemplo, en la gran mayora de las prcticas con el PIC16F84A de este curso vamos a usar la siguiente configuracin:

__config _XT_OSC & _WDT_OFF & _PWRTE_ON


que es equivalente a:

__fuses __config

_XT_OSC & _WDT_OFF & _PWRTE_ON _XT_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF

Para los PIC16F87xA especificaremos los siguientes fuses:

Los fuses no indicados, como la Proteccin de Cdigo, quedarn con su valor por defecto. Para mayor informacin puedes volver al captulo 3.

La directiva equ
Cuando se quiere acceder a los registros (SFR o GPR) de la RAM se les debe referenciar por sus direcciones. Como eso sera una labor muy tediosa, el ensamblador permite identificarlos con un alas o nombre escogido por el usuario mediante la directiva equ. Aunque equ permite igualar (equal = igual) un identificador con cualquier constante nmerica, su principal aplicacin es darles nombres a los registros de la RAM. De hecho, todos los registros SFR del PIC ya estn identificados as en su correspondient e archivo de dispositivo (revsalos, si quieres). A nosotros equ nos servir para trabajar con los registros GPR. Con el siguiente ejemplo se bautizan con cont1 y cont2 a los registros ubicados en las direcciones 0x0C y 0x0D, respectivam ente.

cont1 equ cont2 equ

0x0C 0x0D

; Ubicar cont1 en direccin 0x0C ; Ubicar cont2 en direccin 0x0D

Las directivas cblock y endc


Incluso si usamos la directiva equ para referirnos con ms comodidad a los registros GPR, si nuestro programa va a procesar varios datos y variables, seremos propensos a comenter errores con las designaciones. Las directivas cblock y endc siempre deben ir juntas para formar un bloque de variables que ocupan posiciones consecutivas en la RAM del PICmicro, siendo la direccin de la primera variable la indicada despus de cblock. Para tener un mejor contexto de su uso analicemos el siguiente boceto de cdigo:

processor PIC16F84A
include <P16F84A.inc> cblock 0x0C cont var temp endc ; En el PIC16F84A los registros GPR estn ; disponibles a partir de la direccin 0x0C

org 0x000 Start ; ... call subroutine ; ... goto Start

;************************************************************************** cblock ; Aqu no necesitas establecer una bus ; direccin base del0 endc subroutine ; ... ; ... return end
En el boceto el primer bloque cblock - endc es equivalente a haber puesto las lneas de cdigo:

cont equ 0x0C var equ 0x0D temp equ 0x0E

; Ubicar count en direccin 0x0C ; Ubicar var en direccin 0x0D ; Ubicar temp en direccin 0x0E

Ms abajo aparece otro bloque cblock - endc con dos variables, bus y del0, que tambin se pudieron incluir en el primer bloque, pero que se separan, como muchas veces se preferir, por guardar alguna relacin entre ellas y para tratar de ordenar el cdigo. No obstante, a diferencia de los lenguajes como el C, estos registros sern accesibles desde cualquier parte del programa. Ahora bien, si como dice el comentario, el segundo bloque no necesita una direccin base, qu direcciones les corresponden a esas variables? Como el ensamblador sabe dnde se qued, a las variables del siguiente bloque les asignar las locaciones subsiguientes. Es decir, el segundo cblock - endc sera equivalente a:

bus equ del0 equ

0x0F 0x10

; Ubicar bus en direccin 0x0F ; Ubicar del0 en direccin 0x10

De hecho, en un programa puedes poner varios bloques ms de este tipo, pero sin olvidar que, a menos que sepas lo que haces, solamente el primero debe tener la direccin de la primera variable, inclusive si est vaco.

La directiva org
Su nombre deriva de origen. Es para indicarle al ensamblador a partir de que direccin empezar a mapear el subsiguiente cdigo ejecutable. Como el CPU empieza a ejecutar el cdigo desde la direccin 0x000, al menos la primera instruccin de cdigo debera estar all. Sin embargo, poner org 0x00 en programas con cdigo continuo se ha convertido en un hbito a veces hasta innecesario porque el ensamblador, que no es tan tonto, sabe que por defecto debe colocar el cdigo a partir de la direccin 0x000.

org

0x000

Usar org s es til cuando se quiere reubicar algunas rutinas de cdigo en determinados segmentos de la memoria de programa.

La directiva end
Es la directiva que pone fin a la lectura del cdigo fuente por parte del ensamblador. Cualquier cdigo ubicado despus de esta directiva ya no ser tomado en cuenta, lo que implica que solo debera haber una directiva end por programa, incluso si consta de varios archivos. Son sofisticados los programas donde se puede usar varias veces.

La directiva banksel
El nombre de esta directiva es un acrnimo de BANK SELection y, como se prev, sirve para cambiar de bancos. Como sabemos, la RAM de los PICmicros de familias Baseline y Midrange se divide en varios bancos por los que tenemos que ir saltando para acceder a sus registros, jugando con los bits RP0 y RP1, del registro STATUS, as:
Tabla RP1 RP0

RP1 RP0 Banco accedido 00 Banco 0 01 Banco 1 10 Banco 2 11 Banco 3


En los PIC con dos bancos, como el PIC16F84A, solo se trabaja con el bit RP0. Dado el tedio que puede acarrear este trabajo, sobre todo si no recordamos a qu banco pertenece un registro, la directiva banksel puede ser de gran ayuda. Banksel se encargar de colocar las instrucciones necesarias para acceder al registro que se le indica como parmetro.

banksel TRISA

; Seleccionar banco del registro TRISA (Banco 1)

La directiva #define
Es otra directiva que se utiliza muy a menudo. Los que programaron alguna vez en C/C++ saben cmo funciona. Para los otros, deben saber que tiene tres partes: el mismo define, un identificador y toda la cadena restante.

#define identificador cadena ;


Lo que har el ensamblador es sustituir el identificador por toda la cadena restante tal cual es en cada punto del programa donde se encuentre identificador. Por eso se le conoce como directiva de sustitucin de texto. identificador es una palabra con las mismas reglas impuestas a otros identificadores, como las etiquetas o nombres de registros GPR. En cambio, cadena puede estar formado por cualesquiera otros elementos de cdigo ensamblador. Un tpico ejemplo de define es para establecer los puertos de interface, ms o menos as:

#define switch PORTB, 0


Y cuando ms adelante escribamos, por ejemplo,

btfsc Switch btfsc PORTB, 0 La directiva $

; Ver si switch vale 0 ; Ver si switch vale 0

lo que en realidad entender el ensamblador ser

Recordemos que las etiquetas en el fondo representan las direcciones de las instrucciones a las que preceden y sirven de referencia para las instrucciones de salto. As mismo, la directiva $ marca la direccin de la instruccin actual y, por ejemplo, $ - 2 ser la direccin de la instruccin que est dos posiciones atrs. Normalmente es preferible colocar etiquetas y dejar el uso de $ solo para los casos donde la propensin a cometer errores sea mnima, por ejemplo, para las instrucciones de saltos cortos. A continuacin se muestran dos rutinas de delay de 50 ms aprox. Ambas son equivalentes, solo que la segunda emplea la directiva $ en vez de las etiquetas. Se asume que la variable cont ha sido definida previamente.

delay_50ms movlw .33 movwf cont laba addlw .1 btfss STATUS, Z goto labb ; Saltar a labb decfsz cont, F labb goto laba ; Saltar a laba return delay_50ms movlw .33 movwf cont addlw .1 btfss STATUS, Z goto $ + 2 ; Saltar 2 instrucciones adelante decfsz cont, F goto $ - 4 ; Saltar 4 instrucciones atrs return La directiva dt
Dt construye una tabla de datos a base de instrucciones retlw. Las tablas son matrices de constantes a cuyos elementos se puede acceder secuencialmente mediante una variable ndice. Dt puede recibir uno o ms parmetros separados por comas. Los parmetros de cadenas de texto sern descompuestos en sus letras. Por ejemplo, la siguiente directiva

dt

"test"
retlw retlw retlw retlw 't' 'e' 's' 't'

ser entendida por el ensamblador como:

La directiva errorlevel
Despus de ensamblar o intentar ensamblar el cdigo el ensamblador generar una serie de mensajes, errores y advertencias. Con la directiva errorlevel podemos indicar cules de ellos pueden ser ignorados o reportados. Los errores no se pueden inhibir.

Sus parmetros pueden ser:

0. Indica reportar mensajes, error y advertencias 1. Indica reportar advertencias y errores. 2. Indica reportar errores. - msgnum. Indica no reportar los mensajes identificados por el nmero msgnum. + msgnum. Indica reportar los mensajes identificados por el nmero msgnum.

Los valores de msgnum forman una lista casi interminable que la puedes encontrar en el manual del ensamblador MPASM. Por ejemplo, un clsico mensaje que aparece constantemente incluso cuando el cdigo est escrito correctamente es el 302, que dice Register in operand not in bank 0. Ensure that bank bits are correct. All nos avisa que estamos accediendo a un registro q ue no es del banco 0 y que debemos asegurarnos de estar haciendo lo correcto. Si nos cansamos de verlo, podemos escribir la siguiente directiva.

errorlevel -302 La directiva messg


Sirve para generar mensajes personalizados definidos por el usuario. El mensaje suele ser condicional, para lo que se requiere de algunas otras directivas como if, ifdef, ifndef, else y endif. Ejemplo, la siguiente directiva har surgir el mensaje Este cdigo est realizado para el PIC16F876A, si es que se trata de ensamblar para otro PICmicro. (la constante __16F876A est definida en el archivo de dispositivo P16F876A.inc.)

ifndef __16F876A messg "Este codigo esta realizado para el PIC16F876A" endif Las directivas if, ifdef, ifndef, else y endif
Son directivas para ensamblado condicional. Mediante ellas indicaremos si una o algunas rutinas de cdigo o directivas inclusive sern tomadas en cuenta o no por el ensamblador. Su estructura se muestra a continuacin. El uso del bloque de else es opcional.

if (ifdef o ifndef) condition ; si condition se cumple (o si es una expresin previamente definida) ; Se considerar este cdigo else ; De lo contrario ; Se considerar este cdigo endif
A modo de ejemplo, supongamos que hacemos un programa para el PIC16F84A y que eventualmente querremos cambiar el cdigo para que se pueda ensamblar para el PIC16F877A. Sabemos que los principales cambios a tener en cuenta son el archivo de dispositivo a incluir, la directiva de los fuses, el inicio de los registros GPR y la configuracin del registro ADCON1 de los PIC16F87xA para que el puerto A sea de E/S digital. El siguiente boceto de programa considera estos cuatro puntos y se puede ensamblar para uno u utro microcontrolador tan solo cambiando la directiva processor, aunque tampoco eso sera necesario si el programa se construye desde otro IDE como MPLAB, por ejemplo.

processor PIC16F84A ; Seleccionar PIC destino ifdef __16F877A include <P16F877A.inc> __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF cblock 0x20 endc else ; Si no es PIC16F877A, asumir que es PIC16F84A include <P16F84A.inc> __config _XT_OSC & _WDT_OFF & _PWRTE_ON cblock 0x0C endc endif cblock ; Algunas variables del programa endc

org 0x000 Start ifdef __16F877A ; Si est definido __16F877A banksel ADCON1 movlw 0x06 ; Hacer PORTA digital movwf ADCON1 ; endif ; Resto del cuerpo del programa end

S-ar putea să vă placă și