08.05.2013 Views

Juego de instrucciones del 80C31

Juego de instrucciones del 80C31

Juego de instrucciones del 80C31

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

1. INTRODUCCION<br />

Modos <strong>de</strong> Direccionamiento y Resumen <strong>de</strong> Instrucciones <strong>de</strong>l 80C51<br />

Así como las oraciones están hechas <strong>de</strong> palabras, los programas están hechos <strong>de</strong> <strong>instrucciones</strong>. Cuando los<br />

programas se construyen con lógicas, bien maduradas secuencias <strong>de</strong> <strong>instrucciones</strong>, resultan programas<br />

eficientes, y aún elegantes. Único para cada familia <strong>de</strong> computadoras es su conjunto <strong>de</strong> <strong>instrucciones</strong>, un<br />

repertorio <strong>de</strong> operaciones primitivas tal como "add," "move," o "jump". Estas breves notas introducen el<br />

conjunto <strong>de</strong> <strong>instrucciones</strong> <strong>de</strong>l MCS-51 ® través <strong>de</strong> un examen <strong>de</strong> los modos <strong>de</strong> direccionamiento y ejemplos a<br />

partir <strong>de</strong> situaciones típicas <strong>de</strong> programación. Al final se ofrece una carta resumen <strong>de</strong> todas las <strong>instrucciones</strong><br />

<strong>de</strong> 8051. Técnicas <strong>de</strong> programación no se discuten. Aunque la operación <strong>de</strong>l programa ensamblador se usa<br />

para convertir programas en lenguaje ensamblador (nemotécnicos, etiquetas, etc.) en programas en lenguaje<br />

<strong>de</strong> máquina (códigos binarios). Dichos tópicos se <strong>de</strong>ben ahondar por el estudiante.<br />

El juego <strong>de</strong> <strong>instrucciones</strong> <strong>de</strong>l MCS-51 ® es optimizado para aplicaciones <strong>de</strong> control <strong>de</strong> 8 bits. Provee una<br />

variedad <strong>de</strong> modos <strong>de</strong> direccionamiento rápidos, compactos para acce<strong>de</strong>r la RAM interna para facilitar<br />

operaciones en estructuras pequeñas <strong>de</strong> datos. Tal juego <strong>de</strong> <strong>instrucciones</strong> ofrece soporte extensivo para<br />

variables <strong>de</strong> un bit, permitiendo la manipulación directa <strong>de</strong> bits en control y sistemas lógicos que requieran<br />

procesamiento Booleano.<br />

Es típico <strong>de</strong> los procesadores <strong>de</strong> 8-bits como el 80C51 que sus <strong>instrucciones</strong> tienen códigos <strong>de</strong> operación <strong>de</strong><br />

8 bits. Ello brinda la posibilidad <strong>de</strong> 2 8 = 256 <strong>instrucciones</strong>, <strong>de</strong> las cuales, 255 están implementadas y una está<br />

in<strong>de</strong>finida. A<strong>de</strong>más <strong>de</strong>l código <strong>de</strong> operación, algunas <strong>instrucciones</strong> tienen uno o dos bytes adicionales para<br />

datos o direcciones. En resumen, hay 139 <strong>instrucciones</strong> <strong>de</strong> un byte, 92 <strong>instrucciones</strong> <strong>de</strong> dos bytes, y 24<br />

<strong>instrucciones</strong> <strong>de</strong> 3 bytes. El mapa <strong>de</strong> los Códigos <strong>de</strong> operación al final muestra, para cada código <strong>de</strong><br />

operación, el nemotécnico, el número <strong>de</strong> bytes en la instrucción, y el número <strong>de</strong> ciclos <strong>de</strong> máquina para<br />

ejecutar la instrucción.<br />

2. Modos <strong>de</strong> Direccionamiento<br />

Cuando las <strong>instrucciones</strong> operan sobre datos, surge la cuestión: "Don<strong>de</strong> están los datos?" la respuesta a esta<br />

pregunta yace en los " modos <strong>de</strong> direccionamiento" <strong>de</strong>l 80C51. Hay varios posibles modos <strong>de</strong><br />

direccionamiento y hay varias posibles respuestas a la pregunta, tales como "en el byte 2 <strong>de</strong> la instrucción",<br />

"en el registro R5", "en la dirección directa 38H" o quizás "en la memoria externa <strong>de</strong> datos en la dirección<br />

contenida en el apuntador <strong>de</strong> datos mas el sesgo <strong>de</strong>l acumulador".<br />

Los modos <strong>de</strong> Direccionamiento son una parte integral <strong>de</strong> cada juego <strong>de</strong> instrucción <strong>de</strong> una computadora.<br />

Ellos permiten especificar la fuente o el <strong>de</strong>stino <strong>de</strong> datos en diferentes maneras <strong>de</strong>pendiendo en la situación<br />

<strong>de</strong> la programación. En esta sección, se examinan todos los modos <strong>de</strong> direccionamiento <strong>de</strong>l 8051 y se dan<br />

ejemplos <strong>de</strong> cada uno. Hay ocho modos disponibles:<br />

Registro<br />

Directo<br />

Indirecto<br />

Inmediato<br />

Relativo<br />

Absoluto<br />

Largo<br />

In<strong>de</strong>xado<br />

2.1 Direccionamiento <strong>de</strong> Registro<br />

El programador <strong>de</strong>l 8051 tiene acceso a 8 "registros <strong>de</strong> trabajo" numerados <strong>de</strong> R0 a R7. Las Instrucciones<br />

que usan direccionamiento <strong>de</strong> registro se ensamblan usando los tres bits menos significativos <strong>de</strong>l código <strong>de</strong><br />

operación <strong>de</strong> la instrucción para indicar un registro <strong>de</strong>ntro <strong>de</strong> esta espacio <strong>de</strong> direcciones. Esto es, un código<br />

Profr. Salvador Saucedo 1


<strong>de</strong> función y un operando para dirección se combinan para formar una instrucción corta, <strong>de</strong> un byte. (ver<br />

Figura la).<br />

El lenguaje ensamblador <strong>de</strong>l 8051 indica al direccionamiento <strong>de</strong> registro con el símbolo Rr don<strong>de</strong> r está <strong>de</strong> 0<br />

a 7. Por ejemplo, para añadir el contenido <strong>de</strong>l Registro 7 al acumulador, la siguiente instrucción se usa<br />

ADD A, R7<br />

y el código <strong>de</strong> operación es 00101111B. Los cinco bits superiores, 00101, indican la instrucción, y los tres<br />

bits bajos, 111, el registro. Se pue<strong>de</strong> uno convencer que ese es el código <strong>de</strong> operación correcto buscando esta<br />

instrucción al final <strong>de</strong>l documento.<br />

Hay cuatro "bancos" <strong>de</strong> registros <strong>de</strong> trabajo, pero sólo uno está activo a la vez. Físicamente, los bancos <strong>de</strong><br />

registros ocupan los primeros 32 bytes <strong>de</strong> RAM interna <strong>de</strong> datos (direcciones 00H a 1FH) con bits 4 y 3 <strong>de</strong>l<br />

PSW <strong>de</strong>terminando el banco activo. Un reset <strong>de</strong>l hardware habilita al banco 0, pero un banco diferente es<br />

seleccionado al modificar los bits 4 y 3 <strong>de</strong>l PSW. Por ejemplo, la instrucción<br />

MOV PSW,#00011000B<br />

Activa al banco <strong>de</strong> registros 3 al hacer “1” los bits selectores <strong>de</strong> banco <strong>de</strong> registro (RS1 y RS0) en PSW, bits<br />

en posiciones 4 y 3.<br />

Algunas <strong>instrucciones</strong> son especificas a ciertos registros, tal como el acumulador, el apuntador <strong>de</strong> datos, etc.,<br />

<strong>de</strong> modo que una dirección no es necesaria. El código <strong>de</strong> operación por sí mismo indica el registro. Estas<br />

<strong>instrucciones</strong> "especificas a un registro" se refieren al acumulador como "A", al apuntador <strong>de</strong> datos como<br />

"DPTR", al contador <strong>de</strong> programa como "PC" a la ban<strong>de</strong>ra <strong>de</strong> acarreo como "C" y a la pareja <strong>de</strong> registros<br />

acumulador,B como "AB". Por ejemplo,<br />

INC DPTR<br />

es una instrucción <strong>de</strong> un byte que suma 1 al apuntador <strong>de</strong> datos <strong>de</strong> 16 bits. Consultar al final para <strong>de</strong>terminar<br />

el código <strong>de</strong> operación para esta instrucción.<br />

2.2 Direccionamiento Directo<br />

El direccionamiento Directo pue<strong>de</strong> acce<strong>de</strong>r a cualquier variable interna o registro <strong>de</strong> hardware. Un byte<br />

adicional es agregado al código <strong>de</strong> operación especificando la localidad a ser usada. (Ver Figura 1b).<br />

Dependiendo en el bit <strong>de</strong> mayor or<strong>de</strong>n <strong>de</strong> la dirección directa, uno <strong>de</strong> dos espacios <strong>de</strong> memoria interna es<br />

seleccionado. Cuando el bit 7 = 0, la dirección directa está entre 0 y 127 (00H a 7FH) y las 128 localida<strong>de</strong>s<br />

<strong>de</strong> RAM interna <strong>de</strong> bajo or<strong>de</strong>n son referenciadas. Todos los 110 puertos y registros especiales <strong>de</strong> función,<br />

control, o estado, sin embargo, les asignan direcciones entre 128 y 255 (80H a FFH). Cuando el byte <strong>de</strong><br />

dirección directo está entre estos limites (bit 7 = 1), el correspondiente registro especial <strong>de</strong> función es<br />

accedido. Por ejemplo, Puertos 0 y 1 se asignan direcciones directas 80H y 90H, respectivamente. no es<br />

necesario conocer las direcciones <strong>de</strong> tales registros; el ensamblador permite y entien<strong>de</strong> las abreviaturas <strong>de</strong> los<br />

nemotécnicos ("P0 para el Puerto 0, "TMOD" para el registro <strong>de</strong> modo <strong>de</strong>l timer, etc.). Como ejemplo <strong>de</strong><br />

direccionamiento directo, la instrucción MOV P1,A transfiere el contenido <strong>de</strong>l acumulador al Puerto 1. La<br />

dirección directa <strong>de</strong>l Puerto 1 (90H) se <strong>de</strong>termina por el ensamblador e insertada como el byte 2 <strong>de</strong> la<br />

instrucción. La fuente <strong>de</strong>l dato, el acumulador, se especifica implícitamente en el código <strong>de</strong> operación.<br />

Usando la carta al final como referencia, el código completo <strong>de</strong> esta instrucción es<br />

10001001 – 1er byte (código <strong>de</strong> operación)<br />

100l0000 - 2do byte (dirección <strong>de</strong> P1)<br />

Profr. Salvador Saucedo 2


Fig. 1. Modos <strong>de</strong> Direccionamiento <strong>de</strong>l 80C51. (a) direccionamiento <strong>de</strong> Registro (b) direccionamiento Directo (c)<br />

direccionamiento Indirecto (d) direccionamiento Inmediato (e) direccionamiento Relativo (f) direccionamiento<br />

Absoluto (g) direccionamiento Largo (h) direccionamiento in<strong>de</strong>xado.<br />

2.3 Direccionamiento Indirecto<br />

Cómo es una variable i<strong>de</strong>ntificada si su dirección es <strong>de</strong>terminada, computada, o modificada mientras un<br />

programa está corriendo? Tal situación se presenta cuando se manipulan secuencialmente localida<strong>de</strong>s <strong>de</strong><br />

memoria, el acceso in<strong>de</strong>xado <strong>de</strong>ntro <strong>de</strong> tablas en RAM, números <strong>de</strong> múltiple precisión, o ca<strong>de</strong>nas <strong>de</strong><br />

caracteres. El direccionamiento <strong>de</strong> Registro o directo o pue<strong>de</strong> usarse, ya que ambos requieren que las<br />

direcciones <strong>de</strong> los operandos se sepan a tiempo <strong>de</strong>l ensamblado.<br />

La solución en el 80C51 es el direccionamiento indirecto. R0 y R1 pue<strong>de</strong>n operar como registros<br />

"apuntadores" sus contenidos indican una dirección en RAM don<strong>de</strong> los datos son escritos o leídos. El bit<br />

menos significativo <strong>de</strong>l código <strong>de</strong> operación <strong>de</strong> la instrucción <strong>de</strong>termina qué registro (R0 o R1) se usa como<br />

el apuntador. (ver Figura 1c).<br />

En el lenguaje ensamblador <strong>de</strong>l 8051, el direccionamiento indirecto se representa mediante el signo<br />

comercial "arroba" (@) precediendo a R0 o R1. Como un ejemplo, si R1 contiene 34H y la memoria interna<br />

con dirección 34H contiene 77H, la instrucción<br />

MOV A,@R1<br />

Profr. Salvador Saucedo 3


mueve 77H al acumulador.<br />

El direccionamiento Indirecto es esencial cuando se acce<strong>de</strong> <strong>de</strong> manera secuencial a localida<strong>de</strong>s <strong>de</strong> memoria.<br />

Por ejemplo, la siguiente secuencia <strong>de</strong> <strong>instrucciones</strong> limpia la RAM interna <strong>de</strong>s<strong>de</strong> la dirección 50H hasta la<br />

6FH:<br />

MOV R0, #50H<br />

LAZO: MOV @R0, #0<br />

INC R0<br />

CJNE R0, #70H, LAZO<br />

(continua)<br />

La primera instrucción inicializa R0 con la dirección <strong>de</strong> arranque <strong>de</strong>l bloque <strong>de</strong> memoria; la segunda<br />

instrucción usa el direccionamiento indirecto para mover 00H a la localidad apuntada por R0; la tercera<br />

instrucción incrementa al apuntador (R0) a la siguiente dirección; y la última instrucción prueba al apuntador<br />

para ver si el término <strong>de</strong>l bloque ya fue limpiado. La prueba usa 70H, y no 6FH, porque el incremento ocurre<br />

<strong>de</strong>spués <strong>de</strong>l mover indirecto. Esto garantiza que la localidad final (6FH) sea escrita antes <strong>de</strong> terminar.<br />

2.4 Direccionamiento Inmediato<br />

Cuando el operando fuente es una constante y no una variable (i.e., la instrucción usa un valor conocido al<br />

tiempo <strong>de</strong> ensamblar), entonces la constante pue<strong>de</strong> ser incorporada en la instrucción como un byte <strong>de</strong> dato<br />

"inmediato". Un byte adicional en la instrucción contiene el valor. (ver Figura 1d.)<br />

En lenguaje ensamblador, los operandos inmediatos están precedidos por el signo <strong>de</strong> número (#). El<br />

operando pue<strong>de</strong> ser una constante numérica, una variable simbólica, o una expresión aritmética usando<br />

constantes, símbolos, y operadores. El ensamblador computa el valor y substituye el dato inmediato en la<br />

instrucción. Por ejemplo, la instrucción MOV A, #14 carga el valor 14 (0EH) en el acumulador. (se asume<br />

que la constante "14" está en notación <strong>de</strong>cimal, ya que ella no está seguida por "H").<br />

Con una excepción, todas las <strong>instrucciones</strong> usando direccionamiento inmediato usan una constante <strong>de</strong> 8 bits<br />

como dato para el valor inmediato. Cuando se inicializa al apuntador <strong>de</strong> datos, una constante <strong>de</strong> 16 bits es<br />

requerida. Por ejemplo, MOV DPTR, #2800H es una instrucción <strong>de</strong> 3 bytes que carga la constante 2800H,<br />

<strong>de</strong> 16 bits, en el apuntador <strong>de</strong> datos.<br />

2.5 Direccionamiento Relativo<br />

El direccionamiento Relativo se usa sólo con ciertas <strong>instrucciones</strong> <strong>de</strong> salto. Una dirección relativa (o sesgo)<br />

es un valor <strong>de</strong> 8 bits, signado, el cual se aña<strong>de</strong> al contador <strong>de</strong> programa para formar la dirección <strong>de</strong> la<br />

siguiente instrucción a ejecutarse. Ya que un sesgo <strong>de</strong> 8 bits con signo se usa, el rango para saltos es -128 a<br />

+127 localida<strong>de</strong>s. El sesgo relativo es agregado a la instrucción como un byte adicional. (ver Figura le.)<br />

Previo a la adición, el contador <strong>de</strong> programa es incrementado a la dirección que sigue a la instrucción <strong>de</strong>l<br />

salto; esto es, la nueva dirección es relativa a la siguiente instrucción, no a la la dirección <strong>de</strong> la instrucción<br />

<strong>de</strong>l salto. (ver Figura 2). Normalmente, tal <strong>de</strong>talle no es <strong>de</strong> cuidado para el programador, ya que los <strong>de</strong>stinos<br />

<strong>de</strong>l salto son usualmente especificados como etiquetas y el ensamblador <strong>de</strong>termina el sesgo relativo<br />

a<strong>de</strong>cuado.<br />

Por ejemplo, si la etiqueta THEME representa una instrucción en la localidad 0930H. y la instrucción<br />

SJMP THEME<br />

está en memoria en las localida<strong>de</strong>s 0900H y 09001H, el ensamblador asignará un sesgo relativo <strong>de</strong> 2EH<br />

como el byte 2 <strong>de</strong> la instrucción (0902H +2EH = 0930H).<br />

Profr. Salvador Saucedo 4


Fig. 2. Calculando el sesgo para direccionamiento relativo. (a) Salto corto hacia a<strong>de</strong>lante en memoria. (b) Salto corto<br />

hacia atrás en memoria.<br />

El direccionamiento Relativo ofrece la ventaja <strong>de</strong> proveer código que es in<strong>de</strong>pen<strong>de</strong>n tiente <strong>de</strong> la posición (ya<br />

que direcciones "absolutas" no se usan), pero la <strong>de</strong>sventaja es que los <strong>de</strong>stinos <strong>de</strong> salto están limitados en<br />

rango.<br />

2.6 Direccionamiento Absoluto<br />

El direccionamiento Absoluto es usado sólo con las <strong>instrucciones</strong> ACALL y AJMP. Estas <strong>instrucciones</strong> <strong>de</strong><br />

dos byte permiten brincar <strong>de</strong>ntro <strong>de</strong> la página actual <strong>de</strong> 2KB <strong>de</strong> memoria <strong>de</strong> código al proveer los 11 bits<br />

menos significativos <strong>de</strong> la dirección <strong>de</strong>stino en el código <strong>de</strong> operación (A10-A8) y en el byte 2 <strong>de</strong> la<br />

instrucción (A7-A0). (ver Figura 1f).<br />

Los cinco bits superiores <strong>de</strong> la dirección <strong>de</strong>stino son los actuales cinco bits superiores en el contador <strong>de</strong><br />

programa, así que la instrucción que sigue a la instrucción <strong>de</strong>l brinco y la <strong>de</strong>stino para la instrucción <strong>de</strong>l<br />

brinco <strong>de</strong>ben a<strong>de</strong>ntro <strong>de</strong> la misma página <strong>de</strong> 2KB, ya que A15-A11 no cambian. (ver Figura 3.) Por ejemplo,<br />

si la etiqueta THETE representa una instrucción en la dirección 1686H, y la instrucción<br />

AJMP THETE<br />

está en localida<strong>de</strong>s <strong>de</strong> memoria 1700H y 1701H, el ensamblador codificará a la instrucción como<br />

11000001 – 1er byte (A10-A8 + código <strong>de</strong> operación)<br />

10000110 - 2do byte (A7-A0)<br />

Los bits subrayados son los 11 bits <strong>de</strong> bajo or<strong>de</strong>n <strong>de</strong> la dirección <strong>de</strong>stino, 1686H = 0001011010000110B.<br />

Los 5 bits superiores en el contador <strong>de</strong> programa no cambiarán cuando esa instrucción se ejecute. Notar que<br />

ambas <strong>instrucciones</strong>, la AJMP y la <strong>de</strong>stino están incluidas en la página <strong>de</strong> 2KB acotadas por 1000H y 17FFH<br />

(ver Figura 3). y en consecuencia tienen los cinco bits superiores <strong>de</strong> las direcciones comunes.<br />

El direccionamiento Absoluto ofrece la ventaja <strong>de</strong> <strong>instrucciones</strong> cortas (2 bytes), pero tiene la <strong>de</strong>sventaja <strong>de</strong><br />

limitar el rango para el <strong>de</strong>stino y provee <strong>de</strong> código <strong>de</strong>pendiente <strong>de</strong> la posición.<br />

2.7 Direccionamiento Largo<br />

El Direccionamiento Largo se usa sólo con las <strong>instrucciones</strong> LCALL y LJMP. Tales <strong>instrucciones</strong> <strong>de</strong> 3 bytes<br />

incluyen un <strong>de</strong>stino completo <strong>de</strong> 16 bits <strong>de</strong> la dirección en los bytes 2 y 3 <strong>de</strong> la instrucción.<br />

Profr. Salvador Saucedo 5


(ver Figura 1g.) La ventaja es que el espacio complete <strong>de</strong> 64KB <strong>de</strong> código se pue<strong>de</strong> usar, pero la <strong>de</strong>sventaja<br />

es que las <strong>instrucciones</strong> son <strong>de</strong> tres bytes <strong>de</strong> largo y <strong>de</strong>pen<strong>de</strong>n <strong>de</strong> la posición.<br />

La <strong>de</strong>pen<strong>de</strong>ncia <strong>de</strong> la posición es una <strong>de</strong>sventaja porque el programa no se pue<strong>de</strong> ejecutar en una dirección<br />

diferente. Si, por ejemplo, un programa empieza en 4000H y una instrucción tal como LJMP 4040H aparece,<br />

entonces el programa no se pue<strong>de</strong> mover a, por <strong>de</strong>cir, 6000H. La instrucción LJMP aún salta a la 4040H, la<br />

cual no es la localidad correcta tras que el programa ha sido movido.<br />

Fig. 3 Codificación <strong>de</strong> Instrucciones para direccionamiento absoluto. (a) Mapa <strong>de</strong> memoria con páginas <strong>de</strong> 2KB (b)<br />

Dentro <strong>de</strong> cualquier página <strong>de</strong> 2KB, los 5 bits superiores <strong>de</strong> la dirección son los mismos.<br />

2.8 Direccionamiento ln<strong>de</strong>xado<br />

El direccionamiento in<strong>de</strong>xado usa un registro base (ya sea el contador <strong>de</strong> programa o el apuntador <strong>de</strong> datos)<br />

y un sesgo (el acumulador) para formar la dirección efectiva para una instrucción JMP o MOVC. (ver Figura<br />

1h). Tablas para saltos o tablas <strong>de</strong> búsqueda son creadas fácilmente usando direccionamiento in<strong>de</strong>xado.<br />

Ejemplos se dan al final par alas <strong>instrucciones</strong> MOVC A, @A+< reg _base > y JMP @A+DPTR.<br />

3. Tipos <strong>de</strong> Instrucciones<br />

Las <strong>instrucciones</strong> <strong>de</strong>l 8051 se divi<strong>de</strong>n entre cinco grupos funcionales:<br />

Aritméticas<br />

Lógicas<br />

Transferencia <strong>de</strong> Datos<br />

Variables Booleanas<br />

Ramificado <strong>de</strong> Programa<br />

El Apéndice al final provee una carta <strong>de</strong> referencia rápida mostrando todas las <strong>instrucciones</strong> <strong>de</strong>l 8051 en<br />

grupos funcionales. Una vez se familiarice uno con el juego <strong>de</strong> <strong>instrucciones</strong>, tal carta provee una fuente<br />

rápida y cómoda <strong>de</strong> referencia. Se continúa examinando las <strong>instrucciones</strong> en cada grupo funcional.<br />

3.1 Instrucciones Aritméticas<br />

Las <strong>instrucciones</strong> aritméticas se agrupan juntas en el Apéndice A. Ya que cuatro modos <strong>de</strong> direccionamiento<br />

son posibles, la instrucción ADD A se pue<strong>de</strong> escribir <strong>de</strong> diferentes maneras:<br />

ADD A,7FH (direccionamiento directo)<br />

Profr. Salvador Saucedo 6


ADD A,@R0 (direccionamiento indirecto)<br />

ADD A, R7 (direccionamiento <strong>de</strong> registro)<br />

ADD A,#35H (direccionamiento inmediato)<br />

Todas las <strong>instrucciones</strong> aritméticas se ejecutan en un ciclo <strong>de</strong> máquina excepto la instrucción INC DPTR (2<br />

ciclos <strong>de</strong> máquina) y las <strong>instrucciones</strong> MUL AB y DIV AB (4 ciclos <strong>de</strong> máquina). (Notar que un ciclo <strong>de</strong><br />

máquina toma 1.085 μs si el 80C51 está operando con un cristal <strong>de</strong> 11.0592 MHz).<br />

El 80C51 brinda un direccionamiento muy versátil <strong>de</strong> su espacio <strong>de</strong> memoria interna. Cualquier localidad<br />

pue<strong>de</strong> ser incrementada o <strong>de</strong>crementada usando direccionamiento directo sin ir a través <strong>de</strong>l acumulador. Por<br />

ejemplo, si la localidad <strong>de</strong> RAM interna 7FH contiene 42H. entonces la instrucción<br />

DEC 7FH<br />

<strong>de</strong>crementa su valor, <strong>de</strong>jando 41H en la localidad 7FH.<br />

Tabla 1 Resumen <strong>de</strong> Instrucciones Aritméticas<br />

INSTR. OPERANDOS DESCRIPCION BYTES Periodos <strong>de</strong>l<br />

oscilador<br />

ADD A, Rr Aña<strong>de</strong> Registro al Acumulador 1 12<br />

ADD A, directo Aña<strong>de</strong> byte directo al Acumulador 2 12<br />

ADD A, @Ri Aña<strong>de</strong> RAM indirecta a Acumulador 1 12<br />

ADD A, #dato Aña<strong>de</strong> dato inmediato al Acumulador 2 12<br />

ADDC A,Rr Aña<strong>de</strong> Registro con Carry al Acumulador 1 12<br />

ADDC A, directo Aña<strong>de</strong> byte directo con Carry al Acumulador 2 12<br />

ADDC A, @Ri Aña<strong>de</strong> RAM indirecta con Carry al Acumul. 1 12<br />

ADDC A,#dato Aña<strong>de</strong> dato inmediato con Carry al Acumul. 2 12<br />

SUBB A,Rr Resta Registro con préstamo al Acumulador 1 12<br />

SUBB A,directo Resta byte directo con préstamo al Acumul. 2 12<br />

SUBB A, @Ri Resta RAM indirecta con préstamo al Acumul. 1 12<br />

SUBB A, #dato Resta dato inmediato con préstamo al Acumul. 2 12<br />

INC A Incrementa el Acumulador 1 12<br />

INC Rr Incrementa Registro 1 12<br />

INC directo Incrementa byte directo 2 12<br />

INC @Ri Incrementa RAM indirecta 1 12<br />

DEC A Decrementa Acumulador 1 12<br />

DEC Rr Decrementa Registro 1 12<br />

DEC directo Decrementa byte directo 2 12<br />

DEC @Ri Decrementa RAM indirecta 1 12<br />

INC DPTR Incrementa Apuntador <strong>de</strong> Datos 1 24<br />

MUL AB Multiplica AxB 1 48<br />

DIV AB Divi<strong>de</strong> A entre B 1 48<br />

DA A Ajuste Decimal al Acumulador 1 12<br />

Una <strong>de</strong> las <strong>instrucciones</strong> INC opera en el apuntador <strong>de</strong> datos <strong>de</strong> 16 bits. Ya que el apuntador <strong>de</strong> datos genera<br />

direcciones <strong>de</strong> 16 bits para memoria externa, la operación <strong>de</strong> incrementándolo en uno es muy útil.<br />

Desafortunadamente la instrucción <strong>de</strong>l <strong>de</strong>cremento <strong>de</strong>l apuntador <strong>de</strong> datos no fue implementada y requiere<br />

una secuencia <strong>de</strong> <strong>instrucciones</strong> tal como la siguiente:<br />

DEC DPL ;DECREMENTA BYTE BAJO <strong>de</strong>l DPTR<br />

MOV R7,DPL ;MOVER A R5<br />

CJNE R5,#0FFH,SK ;SI CAE A FF<br />

Profr. Salvador Saucedo 7


DEC DPH ;DECREMENTAR BYTE BAJO TAMBIEN<br />

SK: [continua)<br />

Los bytes alto y bajo <strong>de</strong> DPTR <strong>de</strong>ben ser <strong>de</strong>crementados separadamente; sin embargo, el byte alto (DPH) es<br />

sólo <strong>de</strong>crementado si el byte bajo (DPL) cae <strong>de</strong> 00H a FFH.<br />

La instrucción MUL AB multiplica el acumulador por el dato en el registro B y pone el producto <strong>de</strong> 16 bits<br />

en los registros concatenados B (byte alto) y acumulador (byte bajo). DIV AB divi<strong>de</strong> al acumulador por el<br />

dato en el registro B, <strong>de</strong>jando al cociente <strong>de</strong> 8 bits en el acumulador y el residuo <strong>de</strong> 8 bits en el registro B.<br />

Por ejemplo, si A contiene 125 (7DH) y B contiene 9 (09H), la instrucción<br />

DIV AB<br />

divi<strong>de</strong> al contenido <strong>de</strong> A por el contenido <strong>de</strong> B. El acumulador A se queda con el valor 13 y el acumulador B<br />

se queda con el valor 8 (125/9 = 13 con un residuo <strong>de</strong> 8.)<br />

Para aritmética BCD (<strong>de</strong>cimal codificado en binario); las <strong>instrucciones</strong> ADD y ADDC <strong>de</strong>ben seguirse por<br />

una operación DA A (ajuste <strong>de</strong>cimal) para asegurar el resulta esté en el rango para BCD. Notar que DA A<br />

no convierte un número binario a BCD; ella produce un resultado valido sólo como el segundo paso en la<br />

adición <strong>de</strong> 2 bytes BCD. Por ejemplo, si A contiene el valor BCD 59 (59H), entonces la secuencia <strong>de</strong><br />

<strong>instrucciones</strong><br />

ADD A,#36h<br />

DA A<br />

primero aña<strong>de</strong> 36h a A, dando el resultado 8FH, entonces ajusta el resultado al valor BCD correcto <strong>de</strong> 95<br />

(95H), (59 +36 = 95).<br />

3.2 Instrucciones Lógicas y <strong>de</strong> Rotación<br />

Las <strong>instrucciones</strong> lógicas <strong>de</strong>l 80C51 (ver Apéndice) llevan a cabo operaciones Booleanas (AND, OR,<br />

Exclusive OR, y NOT) en bytes <strong>de</strong> datos en una base <strong>de</strong> bit a bit. Si el acumulador contiene 01110101B,<br />

entonces la siguiente instrucción lógica AND<br />

ANL A, #01010011B<br />

<strong>de</strong>ja al acumulador con 01010001B, lo que es ilustrado <strong>de</strong>bajo.<br />

01010011 (dato inmediato)<br />

AND 01110101 (valor original <strong>de</strong> A)<br />

01010001 (resultado en A)<br />

Ya que los modos <strong>de</strong> direccionamiento para las <strong>instrucciones</strong> lógicas son las mismas que para las<br />

<strong>instrucciones</strong> aritméticas, la instrucción lógica AND pue<strong>de</strong> tomar varias formas:<br />

ANL A.55H (direccionamiento directo)<br />

ANL A, @R0 (direccionamiento indirecto)<br />

ANL A, R6 (direccionamiento <strong>de</strong> registro)<br />

ANL A, #33H (direccionamiento inmediato)<br />

Todas las <strong>instrucciones</strong> lógicas que usan el acumulador como uno <strong>de</strong> los operandos se ejecutan en un ciclo<br />

<strong>de</strong> máquina. Las otras toman dos ciclos <strong>de</strong> máquina.<br />

Las operaciones Lógicas pue<strong>de</strong>n ser realizadas en cualquier byte en el espacio <strong>de</strong> memoria interna <strong>de</strong> datos<br />

sin pasar por el acumulador. La instrucción "XRL directo,#dato” ofrece una manera fácil y rápida <strong>de</strong> invertir<br />

los cuatro bits bajos <strong>de</strong> un puerto, como en<br />

XRL Pl, #0FH<br />

Profr. Salvador Saucedo 8


Esta instrucción lleva a cabo una operación leer-modificar-escribir. Los ocho bits <strong>de</strong>l Puerto 1 son leídos;<br />

entonces cada bit leído es exclusive ORedo con el correspondiente bit en el dato inmediato. Ya que sólo los<br />

cuatro bits bajos <strong>de</strong>l dato inmediato son 1s, el efecto es complementar los 4 bit bajos <strong>de</strong>l puerto. Tal<br />

resultado es reescrito al Puerto 1.<br />

Las <strong>instrucciones</strong> <strong>de</strong> rotación (RL A y RR A) corren al acumulador un bit hacia la izquierda o la <strong>de</strong>recha.<br />

Para una rotación a la izquierda, el bit MSB rota hacia la posición <strong>de</strong>l LSB. Para una rotación a la <strong>de</strong>recha, el<br />

LSB rota hacia la posición <strong>de</strong>l MSB. Las variaciones RLC A y RRC A son rotaciones <strong>de</strong> 9 bits que usan al<br />

acumulador y la ban<strong>de</strong>ra <strong>de</strong> acarreo en el PSW. Si, por ejemplo, la ban<strong>de</strong>ra <strong>de</strong> acarreo contiene 1 y A<br />

contiene 18H, entonces la instrucción<br />

RRC A<br />

Deja a la ban<strong>de</strong>ra <strong>de</strong> acarreo limpia y A igual a 8CH. La ban<strong>de</strong>ra <strong>de</strong> acarreo rota hacia ACC.7 y ACC.0 rota<br />

hacia la ban<strong>de</strong>ra <strong>de</strong> acarreo.<br />

La instrucción SWAP A intercambia los nibbles alto y bajo a<strong>de</strong>ntro <strong>de</strong>l acumulador.<br />

Esta es una operación útil en manipulaciones BCD. Por ejemplo, si el acumulador contiene un número<br />

binario que se sabe que es menor que 100, él es rápidamente convertido a BCD como sigue:<br />

MOV B, #10<br />

DIV AB<br />

SWAP A<br />

ADD A, B<br />

Dividiendo al número por 10 con las primeras dos <strong>instrucciones</strong> <strong>de</strong>ja al digito <strong>de</strong> las <strong>de</strong>cenas en el nibble<br />

bajo <strong>de</strong>l acumulador, y el digito <strong>de</strong> las unida<strong>de</strong>s en el registro B. Las <strong>instrucciones</strong> SWAP y ADD mueven<br />

los dígitos <strong>de</strong> <strong>de</strong>cenas al nibble alto <strong>de</strong>l acumulador, y los dígitos <strong>de</strong> unida<strong>de</strong>s al nibble bajo <strong>de</strong> A.<br />

Tabla 2. Instrucciones lógicas y <strong>de</strong> rotación.<br />

Nemotécnico Operación<br />

Modos Direccionamiento Ciclos <strong>de</strong><br />

DIR IND REG INM máquina<br />

ANL A, A = A and X X X X 1<br />

ANL , A = and A X 1<br />

ANL , #dato = and #dato X 2<br />

ORL A, A = A or X X X X 1<br />

ORL , A = or A X 1<br />

ORL , #dato = or #dato X 2<br />

XRL A, A = A xor X X X X 1<br />

XRL , A = xor A X 1<br />

XRL , #dato = xor #dato X 2<br />

CLR A A = 00h Sólo Acumulador A 1<br />

RL A Rota A 1 bit a izquierda Sólo Acumulador A 1<br />

RLC A Rota A a izq. Través Carry Sólo Acumulador A 1<br />

RR A Rota A 1 bit a <strong>de</strong>recha Sólo Acumulador A 1<br />

RRC A Rota A a <strong>de</strong>r. Través Carry Sólo Acumulador A 1<br />

CPL A A = not A Sólo Acumulador A 1<br />

SWAP A Se intercambian nibbles <strong>de</strong> A Sólo Acumulador A 1<br />

Nota: IND = indirecto (usa @ con Ri)<br />

Profr. Salvador Saucedo 9


3.3 Instrucciones para Transferencia <strong>de</strong> Datos<br />

3.3.1 RAM Interna<br />

Las <strong>instrucciones</strong> que mueven datos a<strong>de</strong>ntro <strong>de</strong>l espacio <strong>de</strong> memoria interna (ver Apéndice A) se ejecutan en<br />

uno o dos ciclos <strong>de</strong> máquina. El formato <strong>de</strong> la instrucción<br />

MOV , <br />

permite que los datos sean transferidos entre cualesquier dos localida<strong>de</strong>s <strong>de</strong> RAM interna o SFR sin pasar<br />

por el acumulador. Recordar, que los 128 bytes altos <strong>de</strong> datos en RAM (8032⁄8052) son accedidos sólo<br />

mediante direccionamiento indirecto, y los SFRs son accedidos sólo mediante direccionamiento directo.<br />

Una característica <strong>de</strong> la arquitectura <strong>de</strong>l MCS-51 ® diferente <strong>de</strong> la mayoría <strong>de</strong> los rnicroprocesadores es que la<br />

pila resi<strong>de</strong> en RAM interna y crece hacia arriba en memoria, hacia direcciones más altas en memoria. la<br />

instrucción PUSH primero incrementa al apuntador <strong>de</strong> la pila (SP), entonces copia el byte en la pila. PUSH y<br />

POP usan direccionamiento directo para i<strong>de</strong>ntificar al byte siendo salvado o restaurado, pero la pila misma es<br />

accedida mediante direccionamiento indirecto usando al registro SP. esto significa que la pila pue<strong>de</strong> usar los<br />

128 bytes altos <strong>de</strong> memoria interna en el 8032⁄8052, los 128 bytes altos <strong>de</strong> memoria interna no se<br />

implementan en los dispositivos 8031⁄8051.<br />

Con tales dispositivos, si el SP es avanzado encima <strong>de</strong> 7FH (127), los bytes PUSHeados se pier<strong>de</strong>n y los<br />

bytes POPeados se in<strong>de</strong>terminan.<br />

Las <strong>instrucciones</strong> <strong>de</strong> transferencia <strong>de</strong> Datos incluyen un MOV <strong>de</strong> 16 bits para inicializar al apuntador <strong>de</strong><br />

datos (DPTR) para búsqueda en tablas en la memoria <strong>de</strong> programa, o para accesos <strong>de</strong> 16-bit en la memoria<br />

externa <strong>de</strong> datos.<br />

El formato <strong>de</strong> instrucción<br />

XCH A, <br />

causa que el acumulador y el byte direccionado intercambien datos. Una instrucción que intercambia<br />

"digitos" <strong>de</strong> la forma<br />

XCHD A. @Ri<br />

es similar, pero sólo los nibbles <strong>de</strong> or<strong>de</strong>n bajo son intercambiados. Por ejemplo, si A contiene F3H, R1<br />

contiene 46H, y la dirección <strong>de</strong> RAM interna 46H contiene 7BH, entonces la instrucción<br />

XCHD A, @R1<br />

Deja a A conteniendo FBH y la localidad <strong>de</strong> RAM interna 46H conteniendo 73H.<br />

Tabla 3. Instrucciones <strong>de</strong> Transferencias en RAM interna.<br />

Nemotécnico Operación<br />

Modos Direccionamiento Pulsos <strong>de</strong><br />

DIR IND REG INM Reloj<br />

MOV A, A =


don<strong>de</strong> Ri es R0 o R1 <strong>de</strong>l banco seleccionado <strong>de</strong> registros), o una dirección <strong>de</strong> dos bytes (@DPTR). La<br />

<strong>de</strong>sventaja en usar direcciones <strong>de</strong> 16 bits es que todos los 8 bits <strong>de</strong>l Puerto 2 se usan como el byte alto <strong>de</strong>l<br />

bus <strong>de</strong> dirección. Esto impi<strong>de</strong> el uso <strong>de</strong>l Puerto 2 como un puerto <strong>de</strong> E/S. Por otro lado, las direcciones <strong>de</strong> 8bits<br />

permiten acce<strong>de</strong>r a unos pocos bytes <strong>de</strong> RAM, sin sacrificar todo el Puerto 2. Todas las <strong>instrucciones</strong><br />

para transferencia <strong>de</strong> datos que operan en memoria externa se ejecutan en 2 ciclos <strong>de</strong> máquina y usan al<br />

acumulador ya sea como la fuente o como el <strong>de</strong>stino <strong>de</strong>l operando.<br />

Los estrobos para leer o escribir la RAM externa ( RD y WR ) se activan sólo durante la ejecución <strong>de</strong> una<br />

instrucción MOVX. Normalmente, estas señales están inactivas (alto). y si la memoria externa <strong>de</strong> datos no se<br />

usa, ambas están disponibles como líneas <strong>de</strong>dicadas <strong>de</strong> E/S.<br />

3.3.3 Búsqueda en Tablas<br />

Dos <strong>instrucciones</strong> para transferencia <strong>de</strong> datos están disponibles para lectura en búsqueda en tablas en<br />

memoria <strong>de</strong> programa. Ya que ambas acce<strong>de</strong>n a memoria <strong>de</strong> programa, la búsqueda en tablas pue<strong>de</strong>n sólo ser<br />

lecturas, no actualizaciones.<br />

El nemotécnico es MOVC por "mover constante". MOVC usa ya sea el contador <strong>de</strong> programa o el apuntador<br />

<strong>de</strong> datos como el e registro base y al acumulador como el sesgo. La instrucción<br />

MOVC A, @A+DPTR<br />

pue<strong>de</strong> acomodar una tabla <strong>de</strong> 256 elementos, enumerados <strong>de</strong> 0 a 255. El número <strong>de</strong>l elemento <strong>de</strong>seado es<br />

cargado en el acumulador y el apuntador <strong>de</strong> datos es inicializado al comienzo <strong>de</strong> la tabla. La instrucción<br />

MOVC A, @A+PC<br />

trabaja <strong>de</strong> la misma manera, excepto que el contador es usado como la dirección base, y la tabla es accedida<br />

a través <strong>de</strong> una subrutina. Primero, el número <strong>de</strong>l elemento <strong>de</strong>seado es puesto en el acumulador, entonces la<br />

subrutina es llamada. La secuencia <strong>de</strong> preparación y llamado podría codificarse como sigue:<br />

MOV A, ENTRY-NÚMERO<br />

CALL BUSCA<br />

BUSCA: INC A<br />

MOVC A, @A+PC<br />

RET<br />

TABLA: DB dato1, dato2, dato3, dato4, . . datoN<br />

La tabla sigue inmediatamente la instrucción RET en memoria <strong>de</strong> programa. La instrucción INC es necesaria<br />

porque el PC apunta a la instrucción RET cuando MOVC se ejecuta. Incrementando el acumulador<br />

efectivamente brinca a la instrucción RET cuando la búsqueda en tabla toma lugar.<br />

3.4 Instrucciones Booleanas<br />

El procesador 80C51 contiene un procesador Booleano completo para operaciones <strong>de</strong> un bit.<br />

La RAM interna contiene 128 bits direccionables, y el espacio <strong>de</strong> SFR soporta hasta 128 bits direccionables<br />

más. Todas las líneas <strong>de</strong> puertos son bit-direccionables, y cada una pue<strong>de</strong> ser tratada como un puerto <strong>de</strong> un<br />

bit separado. las <strong>instrucciones</strong> que acce<strong>de</strong>n tales bits no sólo son brincos condicional, sino también un<br />

repertorio completo <strong>de</strong> <strong>instrucciones</strong> para mover, hacer “1”, hacer “0”, complementar, OR y AND. Tales<br />

operaciones para un bit es una <strong>de</strong> las más po<strong>de</strong>rosas características <strong>de</strong> la familia <strong>de</strong> microcontroladores<br />

MCS-51 ® que no se obtienen fácilmente en otras arquitecturas con operaciones orientadas a bytes.<br />

Las <strong>instrucciones</strong> Booleanas disponibles se muestran en el Apéndice A. Todos los accesos a un bit usan<br />

direccionamiento directo con direcciones <strong>de</strong> bit 00H a 7FH en las 128 localida<strong>de</strong>s más bajas, y direcciones<br />

<strong>de</strong> bit 80H a FFH en el espacio <strong>de</strong> SFRs. Aquellas localida<strong>de</strong>s en los 128 bits más bajos en direcciones <strong>de</strong><br />

Profr. Salvador Saucedo 11


yte 20H a 2FH son numerados secuencialmente <strong>de</strong>s<strong>de</strong> el bit 0 <strong>de</strong> dirección 20H (bit 00H) al bit 7 <strong>de</strong><br />

dirección 2FH (bit 7FH).<br />

Los Bits se pue<strong>de</strong>n hacer 1” o hacer “0” en una simple instrucción. control <strong>de</strong> Simple bit es común para<br />

muchos dispositivos <strong>de</strong> E/S, incluyendo salidas a relevadores, motores, solenoi<strong>de</strong>s, LEDs, buzzers, alarmas,<br />

altavoces, o entradas <strong>de</strong> una variedad <strong>de</strong> switches o indicadores estado. Si una alarma es conectada al Puerto<br />

1 bit 7, por ejemplo, ella pue<strong>de</strong> activarse mediante SETB P1.7 haciendo “1” el bit 7 <strong>de</strong>l puerto, y apagarse al<br />

limpiar el bit <strong>de</strong>l puerto con CLR P1.7. El ensamblador hará lo necesario para efectuar la conversión <strong>de</strong>l<br />

símbolo "P1.7" en la correcta dirección <strong>de</strong>l bit, 97H.<br />

Notar que fácil una ban<strong>de</strong>ra interna se mueve a la pata <strong>de</strong> un puerto:<br />

MOV C, BANDERA<br />

MOV P1.0, C<br />

En este ejemplo, BANDERA es el nombre <strong>de</strong> cualquier bit direccionable en las 128 localida<strong>de</strong>s más bajas o<br />

en el espacio <strong>de</strong> SFR. Una linea <strong>de</strong> E/S (El LSB <strong>de</strong>l Puerto 1, en este caso) es puesto a “1” o a “0”<br />

<strong>de</strong>pendiendo en si el bit BANDERA es 1 o 0.<br />

El bit <strong>de</strong> acarreo en la palabra <strong>de</strong> estado <strong>de</strong>l programa [program status word (PSW)] se usa como el<br />

acumulador <strong>de</strong> un simple bit <strong>de</strong>l procesador Booleano. Las <strong>instrucciones</strong> <strong>de</strong> Bit que hacen referencia al bit <strong>de</strong><br />

acarreo como "C” se ensamblan como <strong>instrucciones</strong> específicas <strong>de</strong> acarreo (i.e. CLR C). El bit <strong>de</strong> acarreo<br />

a<strong>de</strong>más tiene una dirección directa, ya que él resi<strong>de</strong> en el registro PSW, que es bit-direccionable. Como otros<br />

SFRs bit-direccionable, los bits <strong>de</strong>l PSW tienen nemotécnicos pre<strong>de</strong>finidos que el ensamblador acepta como<br />

alias <strong>de</strong> la dirección <strong>de</strong>l bit. El alias <strong>de</strong> la ban<strong>de</strong>ra <strong>de</strong> acarreo es " CY", que está <strong>de</strong>finido como la dirección<br />

<strong>de</strong> bit 0D7H. Consi<strong>de</strong>rar las siguientes dos <strong>instrucciones</strong>:<br />

CLR C<br />

CLR CY<br />

Ambas causan el mismo efecto, sin embargo, la primera es una instrucción <strong>de</strong> un byte. Mientras que la<br />

última es una instrucción <strong>de</strong> dos bytes. En e postrer caso, el segundo byte es la dirección directa <strong>de</strong>l bit<br />

especificado, la ban<strong>de</strong>ra <strong>de</strong> acarreo.<br />

Notar que las operaciones booleanas incluyen <strong>instrucciones</strong> ANL (AND lógico) y ORL (OR lógico), pero no<br />

la operación XRL (OR exclusivo lógico). Una operación XRL es simple <strong>de</strong> implementar. Suponer, por<br />

ejemplo, que es requerido el formar el OR exclusivo <strong>de</strong> dos bits, BITl y BIT2, y <strong>de</strong>jar el resultado en la<br />

ban<strong>de</strong>ra <strong>de</strong> acarreo. Las <strong>instrucciones</strong> se dan <strong>de</strong>bajo.<br />

MOV C, BIT1<br />

JNB BIT2, DONE<br />

CPL C<br />

DONE: (continua)<br />

Primero, BITl es movido a la ban<strong>de</strong>ra <strong>de</strong> acarreo. Si BIT2 = 0, entonces C contiene el resultado correcto; que<br />

es, BIT1 ⊕ BIT2 = BITl si BIT2 = 0. Si BIT2 = 1, C contiene el complemento <strong>de</strong>l resultado correcto.<br />

Complementando C se completa la operación.<br />

3.4.1 Pruebas <strong>de</strong> Bits<br />

El código en el ejemplo anterior usa la instrucción JNB, una <strong>de</strong> una serie <strong>de</strong> <strong>instrucciones</strong> que prueban bits y<br />

que saltan si el bit direccionado es “1” (JC. JB, JBC) o si el bit direccionado es “0” (JNC, JNB). En el caso<br />

anterior, si BIT2 = 0 la instrucción CPL es saltada. JBC (salta si bit es “1” y entonces limpia el bit) ejecuta el<br />

salto si el bit direccionado es “1”, y también limpia el bit; es <strong>de</strong>cir, una ban<strong>de</strong>ra pue<strong>de</strong> ser probada y limpiada<br />

en una simple instrucción.<br />

Todos los bits <strong>de</strong>l PSW son direccionables directamente, así que el bit <strong>de</strong> paridad o las ban<strong>de</strong>ras <strong>de</strong> propósito<br />

general, por ejemplo, son también viables para <strong>instrucciones</strong> que prueban bits.<br />

Profr. Salvador Saucedo 12


3.5 Instrucciones para Ramificación <strong>de</strong>l Programas<br />

Como se evi<strong>de</strong>ncia en el Apéndice A, hay numerosas <strong>instrucciones</strong> para controlar el flujo <strong>de</strong> programas,<br />

incluyendo aquéllas que llaman y retornan <strong>de</strong>s<strong>de</strong> subrutinas o brincan condicionalmente o<br />

incondicionalmente. Tales posibilida<strong>de</strong>s se aumentan aún más mediante los tres modos <strong>de</strong> direccionamiento<br />

para las <strong>instrucciones</strong> <strong>de</strong> ramificación <strong>de</strong> programas.<br />

Hay tres variaciones <strong>de</strong> la instrucción JMP: SJMP, LJMP, y AJMP (usando direccionamientos relativo,<br />

largo, y absoluto, respectivamente). El ensamblador <strong>de</strong> Intel (ASM.51) permite el uso <strong>de</strong>l nemotécnico<br />

genérico JMP si el programador no se preocupa <strong>de</strong> cual variación es codificada. Ensambladores <strong>de</strong> otras<br />

compañías no ofrecen esta versatilidad. El JMP genérico se ensambla como AJMP si el <strong>de</strong>stino no contiene<br />

referencias hacia a<strong>de</strong>lante y está a<strong>de</strong>ntro <strong>de</strong> la misma pagina <strong>de</strong> 2KB (como la instrucción que sigue a<br />

AJMP). De otro modo, ella se ensambla como LJMP. La instrucción genérica CALL (ver <strong>de</strong>bajo) trabaja <strong>de</strong><br />

igual manera.<br />

La instrucción SJMP especifica la dirección <strong>de</strong>stino como un sesgo relativo, como se muestra en la discusión<br />

anterior sobre los modos <strong>de</strong> direccionamiento. Ya que la instrucción es <strong>de</strong> dos bytes <strong>de</strong> largo (uno <strong>de</strong> código<br />

<strong>de</strong> operación más el sesgo relativo), la distancia <strong>de</strong>l salto está limitado <strong>de</strong> -128 a +127 bytes relativo a la<br />

dirección que sigue a la SJMP.<br />

La instrucción LJMP especifica la dirección <strong>de</strong>stino como una constante <strong>de</strong> 16 bits. Ya que la instrucción es<br />

<strong>de</strong> tres bytes <strong>de</strong> largo (uno <strong>de</strong> código <strong>de</strong> operación más dos bytes <strong>de</strong> dirección), la dirección <strong>de</strong>stino pue<strong>de</strong><br />

ser don<strong>de</strong> sea en el espacio <strong>de</strong> 64KB <strong>de</strong> memoria <strong>de</strong> programa.<br />

La instrucción AJMP especifica la dirección <strong>de</strong>stino como una constante <strong>de</strong> 11 bits. Como con SJMP, esta<br />

instrucción es dos bytes <strong>de</strong> largo, pero la codificación es diferente. El código <strong>de</strong> operación contiene 3 <strong>de</strong> los<br />

11 bits <strong>de</strong> la dirección, y el byte 2 tiene los ocho bits bajos <strong>de</strong> la dirección <strong>de</strong>stino. Cuando la instrucción se<br />

ejecuta, esos 11 bits remplazan los 11 bits <strong>de</strong> bajo or<strong>de</strong>n en el PC, y los cinco bits <strong>de</strong> alto or<strong>de</strong>n en el PC<br />

permanecen los mismos. El <strong>de</strong>stino, por tanto, <strong>de</strong>be estar a<strong>de</strong>ntro <strong>de</strong>l mismo bloque <strong>de</strong> 2KB como la<br />

instrucción que sigue a la AJMP. Ya que hay 64KB <strong>de</strong> espacio <strong>de</strong> memoria <strong>de</strong> código, hay 32 <strong>de</strong> esos<br />

bloques, cada iniciando en direcciones con límites en 2KB (0000H. 0800H, 1000H, 1800H, etc., hasta<br />

F800H; ver Figura 3).<br />

En todos los casos el programador especifica la dirección <strong>de</strong>stino al ensamblador en la manera usual como<br />

una etiqueta o como una constante <strong>de</strong> 16 bits. El ensamblador pondrá la dirección <strong>de</strong>stino en el formato<br />

correcto para la instrucción dada. Si el formato requerido por la instrucción no soporta la distancia para la<br />

especificada dirección <strong>de</strong>stino, un mensaje "<strong>de</strong>stine out <strong>de</strong> range" es enviado.<br />

3.5.1 Tablas para Saltos<br />

La instrucción JMP @A+DPTR soporta saltos <strong>de</strong>pendientes <strong>de</strong> el caso para tablas <strong>de</strong> salto. La dirección<br />

<strong>de</strong>stino se computa al tiempo <strong>de</strong> ejecución como la suma <strong>de</strong>l registro DPTR <strong>de</strong> 16 bits y el acumulador.<br />

Típicamente, el DPTR es cargado con la dirección <strong>de</strong> la tabla <strong>de</strong> saltos, y el acumulador actúa como un<br />

índice. Si, por ejemplo, seis "casos" se <strong>de</strong>sean, un valor <strong>de</strong> 0 a 5 es cargado en el acumulador y el salto al<br />

caso apropiado se logra como sigue:<br />

MOV DPTR,#SALTO_TABLA<br />

MOV A,INDICE_NÚMERO<br />

RL A<br />

JMP @A+DPTR<br />

La instrucción RL A arriba convierte el número índice (0 a 5) a un número par en el rango 0 a 10, porque<br />

cada elemento en la tabla <strong>de</strong> saltos es una instrucción <strong>de</strong> dos bytes:<br />

SALTO_TABLA: AJMP CASO0<br />

Profr. Salvador Saucedo 13


AJMP CASO1<br />

AJMP CASO2<br />

AJMP CASO3<br />

AJMP CASO4<br />

3.5.2 Subrutinas e Interrupciones<br />

Hay dos variaciones <strong>de</strong> la instrucción CALL: ACALL y LCALL, usando direccionamiento absoluto y largo,<br />

respectivamente. Como con JMP, el nemotécnico genérico CALL pue<strong>de</strong> usarse con el ensamblador <strong>de</strong> Intel<br />

si el programador no le preocupa el modo en que la dirección es codificada. Cualquier instrucción apila el<br />

contenido <strong>de</strong>l contador <strong>de</strong> programa en la pila y carga al contador <strong>de</strong> programa con la dirección especificada<br />

en la instrucción.<br />

Notar que el PC contiene la dirección <strong>de</strong> la instrucción que sigue a la instrucción CALL cuando él es<br />

empujado (pushed) en la pila. El PC es puesto en la pila primero el byte bajo, <strong>de</strong>spués el byte alto. Esos bytes<br />

son recuperados <strong>de</strong> la pila en el or<strong>de</strong>n reverso. Por ejemplo, si una instrucción LCALL está en memoria <strong>de</strong><br />

código en localida<strong>de</strong>s 2100H-2102H y el SP contiene 60H, entonces LCALL (a) pone la dirección <strong>de</strong> retorno<br />

(2103H) en la pila, en RAM interna, colocando 03H en 61H y 21H en 62H; (b) <strong>de</strong>ja al SP conteniendo 62H;<br />

y (c) salta a la subrutina al cargar al PC con la dirección contenida en bytes 2 y 3 <strong>de</strong> la instrucción.<br />

Las <strong>instrucciones</strong> LCALL y ACALL tienen las mismas restricciones en la dirección <strong>de</strong>stino como las<br />

<strong>instrucciones</strong> JMP y AJMP recién discutidas.<br />

Las subrutinas <strong>de</strong>ben terminar con la instrucción RET, la que retorna la ejecución a la instrucción que sigue a<br />

la CALL. No hay nada mágico acerca <strong>de</strong> la manera en que la instrucción RET regresa al programa principal.<br />

Ella simplemente "popea" los últimos dos bytes <strong>de</strong> la pila y los pone en el contador <strong>de</strong> programa. hay una<br />

regla cardinal <strong>de</strong> programación con subrutinas que ellas <strong>de</strong>ben siempre ser entradas con una instrucción<br />

CALL, y ellas <strong>de</strong>ben siempre ser <strong>de</strong>jadas con una instrucción RET. Saltando hacia a<strong>de</strong>ntro o hacia afuera <strong>de</strong><br />

una subrutina <strong>de</strong> cualquier otro modo usualmente <strong>de</strong>sbalancea la pila y causa que el programa se pierda.<br />

RETI se usa para retornar <strong>de</strong>s<strong>de</strong> una rutina <strong>de</strong> servicio a interrupción (ISR). La única diferencia entre RET y<br />

RETl es que RETI señala al sistema <strong>de</strong> control <strong>de</strong> interrupciones que la interrupción activa fue atendida. Si<br />

no hay interrupciones pendientes al tiempo que RETI se ejecuta, entonces RETI es funcionalmente idéntica<br />

a RET.<br />

3.5.3 Saltos Condicionales<br />

El 8051 ofrece una variedad <strong>de</strong> <strong>instrucciones</strong> <strong>de</strong> saltos condicionales. Todas ellas especifican la dirección<br />

<strong>de</strong>stino usando direccionamiento relativo y por ello están limitadas a distancias <strong>de</strong> salto <strong>de</strong> -128 a +127 bytes<br />

<strong>de</strong>s<strong>de</strong> la instrucción que sigue a la instrucción <strong>de</strong> salto condicional. Notar, sin embargo, que el usuario<br />

especifica la dirección <strong>de</strong>stino <strong>de</strong> la misma manera como con los otros saltos, con una etiqueta o una<br />

constante <strong>de</strong> 16-bits. El ensamblador hace el resto<br />

.<br />

No hay ban<strong>de</strong>ra <strong>de</strong> 0 en el PSW. Las <strong>instrucciones</strong> JZ y JNZ prueban al acumulador <strong>de</strong> datos por tal<br />

condición.<br />

La instrucción DJNZ (<strong>de</strong>crementa y salta si no cero) es para lazos <strong>de</strong> control. Para ejecutar un lazo N veces,<br />

cargar un byte contador con N y terminar el lazo con una DJNZ hacia el inicio <strong>de</strong>l lazo, según se muestra<br />

<strong>de</strong>bajo para N = 9.<br />

MOV R7, #9<br />

LAZO: (empieza el lazo)<br />

⋅<br />

⋅<br />

⋅<br />

(termina el lazo)<br />

DJNZ R7, LAZO<br />

Profr. Salvador Saucedo 14


(continua)<br />

La instrucción CJNE (compara y salta si no igual) es también usada para lazos <strong>de</strong> control. Dos bytes son<br />

especificados en el campo <strong>de</strong> operandos <strong>de</strong> la instrucción y el salto es ejecutado sólo si los dos bytes no son<br />

iguales. Si, por ejemplo, un carácter ha sido recién leído hacia el acumulador <strong>de</strong>s<strong>de</strong> el puerto serial y es<br />

<strong>de</strong>seado saltar hacia una instrucción i<strong>de</strong>ntificada mediante la etiqueta TERMINA si el carácter es SYN<br />

(16H), entonces las siguientes <strong>instrucciones</strong> pudieran ser usadas:<br />

CJNE A, #16H, SKIP<br />

SJMP TERMINA<br />

SKIP: (continua)<br />

Puesto que el salto ocurre sólo si A ≠ SYN, un salto es usado para sobrepasar la instrucción que efectúa el<br />

salto que termina, excepto cuando el código <strong>de</strong> sincronía es leído.<br />

Otra aplicación <strong>de</strong> esta instrucción es en comparaciones "mayor que" o "menor que". Los dos bytes en el<br />

campo <strong>de</strong> operandos se toman como enteros sin signo. Si el primero es menor que el segundo, la ban<strong>de</strong>ra <strong>de</strong><br />

acarreo se hace “1”. Si el primero es mayor o igual al segundo, la ban<strong>de</strong>ra <strong>de</strong> acarreo es limpiada. Por<br />

ejemplo, si se <strong>de</strong>sea brincar a BIG si el valor en el acumulador es mayor que o igual a 39H, las siguientes<br />

<strong>instrucciones</strong> pudieran ser usadas:<br />

CJNE A, #39H, $+3<br />

JNC BIG<br />

El <strong>de</strong>stino <strong>de</strong>l salto para CJNE se especifica como "$+3." El signo <strong>de</strong> dólar ($) es un símbolo especial <strong>de</strong>l<br />

ensamblador representando la dirección <strong>de</strong> la instrucción actual. Ya que CJNE es una instrucción <strong>de</strong> 3 bytes,<br />

"$+3" es la dirección <strong>de</strong> la siguiente instrucción, JNC. En otras palabras, la instrucción CJNE es seguida por<br />

la instrucción JNC sin importar el resultado <strong>de</strong> la comparación. El único propósito <strong>de</strong> la comparación es<br />

afectar a la ban<strong>de</strong>ra <strong>de</strong> acarreo. la instrucción JNC <strong>de</strong>ci<strong>de</strong> si o no el salto toma lugar. Tal ejemplo es una<br />

instancia en la cual el método <strong>de</strong>l 8051 a una situación común <strong>de</strong> programación es más grotesco que con la<br />

mayoría <strong>de</strong> los <strong>de</strong>más microprocesadores; sin embargo, el uso <strong>de</strong> macros permite secuencias <strong>instrucciones</strong><br />

muy productivas, como el ejemplo dado.<br />

EJEMPLOS<br />

Ejemplo 1. Suma <strong>de</strong> dos números con varios dígitos.<br />

1 0000 datos equ 30h ; suma dos numeros BCD <strong>de</strong> 4 bytes<br />

2 0000 ; usando ajuste <strong>de</strong>cimal 12'849,528 + 6'373,463 = 19'222,991<br />

3 0000 org 0<br />

4 0000 753012 mov datos, #12h ; mueve datos a RAM interna<br />

5 0003 753184 mov datos+1,#84h<br />

6 0006 753295 mov datos+2,#95h<br />

7 0009 753328 mov datos+3,#28h<br />

8 000C 753406 mov 34h, #06<br />

9 000F 753537 mov 35h, #37h<br />

10 0012 753634 mov datos+6,#34h<br />

11 0015 753763 mov 37h,#63h ; mueve el ultimo dato BCD<br />

12 0018 ; prepara...<br />

13 0018 7A04 mov R2,#4 ; cuatro sumas<br />

14 001A 7933 mov R1,#datos+3 ; inicia apuntador<br />

15 001C 7837 mov R0,#datos+7 ; inicia apuntador<br />

16 001E<br />

17 001E C3 clr c<br />

18 001F E7 lazo1: mov A,@R1 ; usa modo indirecto<br />

19 0020 36 addc A,@R0 ; suma con el carry<br />

20 0021 D4 da A ; ajuste <strong>de</strong>cimal<br />

21 0022 F7 mov @R1,A ; salva resultado parcial<br />

22 0023 19 <strong>de</strong>c R1<br />

Profr. Salvador Saucedo 15


23 0024 18 otro: <strong>de</strong>c R0 ; incrementa apuntador interno<br />

24 0025 DAF8 djnz R2,lazo1 ; llego al final? salta si no<br />

25 0027 00 nop<br />

26 0028<br />

27 0028 end<br />

Ejemplo 2. Or<strong>de</strong>na números <strong>de</strong> 8 bits con signo.<br />

1 0000 ; or<strong>de</strong>na 7 numeros con signo con metodo burbuja <strong>de</strong> modo ascen.<br />

2 0000 ; intercambia bytes si N exOR V = "1"; N = MSB <strong>de</strong> la resta<br />

3 0000 datos equ 30h<br />

4 0000 org 0<br />

5 0000 75305D mov datos, #93 ; mueve datos a la RAM interna<br />

6 0003 7531D3 mov datos+1,#-45<br />

7 0006 7532A9 mov datos+2,#-87 ; = A9H<br />

8 0009 753310 mov datos+3,#16<br />

9 000C 75346D mov datos+4,#109 ; = 6DH<br />

10 000F 753525 mov datos+5,#37<br />

11 0012 7536BC mov datos+6,#-68 ; mueve el ultimo dato = BCH<br />

12 0015 ; or<strong>de</strong>na...<br />

13 0015 7930 mov R1,#datos ; inicia apuntador externo<br />

14 0017 E9 lazo1: mov A,R1<br />

15 0018 F8 mov R0,A ; inicia apuntador interno<br />

16 0019 08 inc R0<br />

17 001A E7 lazo2: mov A,@R1 ; usa modo indirecto<br />

18 001B C3 clr c ; limpia el carry<br />

19 001C 96 subb A,@R0<br />

20 001D 20D205 jb ov,uno ; brinca si V = 1<br />

21 0020 33 rlc A ; pone bit <strong>de</strong> signo en el carry<br />

22 0021 4008 jc otro ; usar jnc para or<strong>de</strong>nar <strong>de</strong>scen<strong>de</strong>nte<br />

23 0023 8003 sjmp cambia<br />

24 0025 33 uno: rlc A ; pone bit <strong>de</strong> signo en el carry<br />

25 0026 5003 jnc otro ; usar jc para or<strong>de</strong>nar <strong>de</strong>scen<strong>de</strong>nte<br />

26 0028 E7 cambia: mov A,@R1 ; intercambia contenido <strong>de</strong><br />

localida<strong>de</strong>s<br />

27 0029 C6 xch A,@R0<br />

28 002A F7 mov @R1,A<br />

29 002B 08 otro: inc R0 ; incrementa apuntador interno<br />

30 002C B837EB cjne R0,#datos+7,lazo2 ; llego al fin salta si no<br />

31 002F 00 nop<br />

32 0030 09 inc R1 ; incrementa apuntador externo<br />

33 0031 B936E3 cjne R1,#datos+6,lazo1 ; llego al fin salta si no<br />

34 0034 00 nop<br />

35 0035<br />

36 0035 end<br />

Ejemplo 3. Multiplicación <strong>de</strong> dos números <strong>de</strong> 8 bits empleando la ley <strong>de</strong> signos.<br />

1 0000 ; multiplica numeros <strong>de</strong> 8 bits con signo<br />

2 0000 testigo bit 28h ; para usar ley <strong>de</strong> signos<br />

3 0000 NB bit 0f7h ; bit <strong>de</strong> signo <strong>de</strong> B<br />

4 0000 NA bit 0E7h ; bit <strong>de</strong> signo <strong>de</strong> A<br />

5 0000 primera equ 30h<br />

6 0000 org 0<br />

7 0000 801E sjmp 20h<br />

8 0020 org 20h<br />

9 0020 753047 mov primera, #47h ; 71x<br />

10 0023 753155 mov primera+1,#55h ; 85 = 6035 = 1793h<br />

Profr. Salvador Saucedo 16


11 0026 753485 mov primera+4,#85h ; -123x<br />

12 0029 753520 mov primera+5,#20h ; 32 = -3936 = F0A0h<br />

13 002C 753885 mov primera+8,#85h ; -123x<br />

14 002F 753993 mov primera+9,#93h ; -109 = 13,407 = 345Fh<br />

15 0032 7830 mov R0,#primera<br />

16 0034 86F0 lazo: mov B,@R0 ; trae 1er factor<br />

17 0036 08 inc R0 ; incrementa apuntador<br />

18 0037 E6 mov A,@R0 ; trae 2do factor<br />

19 0038 1144 acall mul2s ; multiplica ambos<br />

20 003A 08 inc R0<br />

21 003B A6F0 mov @R0,B ; salva parte alta <strong>de</strong>l producto<br />

22 003D 08 inc R0<br />

23 003E F6 mov @R0,A ; salva parte baja <strong>de</strong>l producto<br />

24 003F 08 inc R0<br />

25 0040 B83CF1 cjne R0,#03ch,lazo ; termino ?, brinc si no<br />

26 0043 00 nop<br />

27 0044<br />

28 0044 C228 mul2s: clr testigo<br />

29 0046 30F70C jnb NB,otro ; brinca si 1er factor es positivo<br />

30 0049 B228 cpl testigo ; hace testigo 1<br />

31 004B C0E0 push A ; salva Acc en pila<br />

32 004D C5F0 xch A,B ;<br />

33 004F F4 cpl A ; complementa a 1s<br />

34 0050 04 inc A ; complemento a 2s<br />

35 0051 C5F0 xch A,B ; B = negativo <strong>de</strong> B<br />

36 0053 D0E0 pop A ; recupera Acc<br />

37 0055 30E704 otro: jnb NA,mult ; brinca si 2do factor es positivo<br />

38 0058 B228 cpl testigo ; complementa testigo<br />

39 005A F4 cpl A ; complemento a 1s <strong>de</strong> Acc<br />

40 005B 04 inc A ; Acc = negativo <strong>de</strong> Acc<br />

41 005C A4 mult: mul ab ; multiplica dos positivos<br />

42 005D 302812 jnb testigo,fin ; si testigo = 0, OK<br />

43 0060 ; complementa el producto (16 bits) a doses<br />

44 0060 C0E0 push A<br />

45 0062 C5F0 xch A,B<br />

46 0064 F4 cpl A ; complementa a 1s byte alto<br />

47 0065 C5F0 xch A,B<br />

48 0067 D0E0 pop A ; recupera byte bajo<br />

49 0069 F4 cpl A ; complementa a 1s byte bajo<br />

50 006A 2401 add a,#1 ; lo complementa a doses<br />

51 006C C5F0 xch A,B<br />

52 006E 3400 addc A,#0 ; si necesita ajusta byte alto<br />

53 0070 C5F0 xch A,B ; resultado en B:A<br />

54 0072 22 fin: ret<br />

55 0073 end<br />

Ejemplo 4. Cálculo <strong>de</strong>l CRC <strong>de</strong> una ca<strong>de</strong>na ASCIIZ, usando una tabla.<br />

1 0000 ; Calcula el Codigo <strong>de</strong> Redundancia Ciclica (CRC) <strong>de</strong> una ca<strong>de</strong>na<br />

2 0000 CRC1 equ 30h ; RAM interna<br />

3 0000 CRC0 equ CRC1+1<br />

4 0000 org 0<br />

5 0000 801E sjmp 20h<br />

6 0020 org 20h<br />

7 0020 753000 mov CRC1,#0 ; limpia parte alta <strong>de</strong>l resultado<br />

8 0023 753100 mov CRC0,#0 ; limpia parte baja <strong>de</strong>l resultado<br />

9 0026 7435 mov A,#ca<strong>de</strong>na-miPC ; forma sesgo a ca<strong>de</strong>na<br />

10 0028<br />

Profr. Salvador Saucedo 17


11 0028 C0E0 mas: push a<br />

12 002A 83 movc A,@A+PC ; trae un caracter<br />

13 002B<br />

14 002B ; coteja si llego el nulo...<br />

15 002B 600A miPC: jz final ; si, brinca<br />

16 002D 900200 mov dptr,#tabla+100h ; Trae valor <strong>de</strong> 2da parte <strong>de</strong> tabla<br />

17 0030 113A acall updcrc ; actualiza el CRC<br />

18 0032 D0E0 pop a ; recupera acum. <strong>de</strong> la pila<br />

19 0034 04 inc a ; incrementa el sesgo<br />

20 0035 80F1 sjmp mas ; va por otro caracter<br />

21 0037 D0E0 final: pop a<br />

22 0039 00 nop ; the end, folks!<br />

23 003A<br />

24 003A ; rutina que actualiza el CRC usando la tabla<br />

25 003A updcrc:<br />

26 003A 6530 xrl a, CRC1 ; exclusive or<br />

27 003C C3 clr c ; limpia carry<br />

28 003D 33 rlc a, ; por 2<br />

29 003E FA mov R2,A ; salva indice<br />

30 003F 4003 jc sdo<br />

31 0041 900100 mov DPTR,#tabla ; apunta a parte baja <strong>de</strong> tabla<br />

32 0044 93 sdo: movc a,@a+dptr ; Trae valor <strong>de</strong> tabla<br />

33 0045 F9 mov R1,A<br />

34 0046 EA mov A,R2<br />

35 0047 04 inc A<br />

36 0048 93 movc a,@a+dptr ; Trae valor <strong>de</strong> tabla<br />

37 0049 6531 xrl a, CRC0 ; XOR con parte baja <strong>de</strong> CRC anterior<br />

38 004B F530 mov CRC1,a<br />

39 004D E9 mov A,R1<br />

40 004E F531 mov CRC0,a<br />

41 0050<br />

42 0050 22 ret<br />

43 0051<br />

45 0060 org 60h<br />

46 0060 45 6C 20 ca<strong>de</strong>na: db 'El laberinto <strong>de</strong>l mono',0<br />

0063 6C 61 62 65 72 69<br />

0069 6E 74 6F 20 64 65<br />

006F 6C 20 6D 6F 6E 6F 00<br />

47 0100 org 100h<br />

48 0100 tabla:<br />

49 0100 00 00 dw 0000h, 1021h, 2042h, 3063h, 4084h, 50a5h, 60c6h, 70e7h<br />

0102 21 10 42 20<br />

0106 63 30 84 40<br />

010A A5 50 C6 60<br />

010E E7 70<br />

50 0110 08 81 dw 8108h, 9129h, 0a14ah, 0b16bh, 0c18ch, 0d1adh, 0e1ceh,<br />

0f1efh<br />

0112 29 91 4A A1<br />

0116 6B B1 8C C1<br />

011A AD D1 CE E1<br />

011E EF F1<br />

51 0120 31 12 dw 1231h, 0210h, 3273h, 2252h, 52b5h, 4294h, 72f7h, 62d6h<br />

0122 10 02 73 32<br />

0126 52 22 B5 52<br />

012A 94 42 F7 72<br />

012E D6 62<br />

52 0130 39 93 dw 9339h, 8318h, 0b37bh, 0a35ah,0d3bdh, 0c39ch, 0f3ffh,0e3<strong>de</strong>h<br />

0132 18 83 7B B3<br />

Profr. Salvador Saucedo 18


0136 5A A3 BD D3<br />

013A 9C C3 FF F3<br />

53 0140 62 24 dw 2462h, 3443h, 0420h, 1401h, 64e6h, 74c7h, 44a4h, 5485h<br />

0142 43 34 20 04<br />

0146 01 14 E6 64<br />

014A C7 74 A4 44<br />

54 0150 6A A5 dw 0a56ah, 0b54bh, 8528h, 9509h,0e5eeh, 0f5cfh,0c5ach,0d58dh<br />

0152 4B B5 28 85<br />

0156 09 95 EE E5<br />

015A CF F5 AC C5<br />

55 0160 53 36 dw 3653h, 2672h, 1611h, 0630h, 76d7h, 66f6h, 5695h, 46b4h<br />

56 0170 5B B7 dw 0b75bh, 0a77ah,9719h, 8738h, 0f7dfh, 0e7feh, 0d79dh,0c7bch<br />

57 0180<br />

58 0180 C4 48 dw 48c4h, 58e5h, 6886h, 78a7h, 0840h, 1861h, 2802h, 3823h<br />

59 0190 CC C9 dw 0c9cch, 0d9edh, 0e98eh, 0f9afh, 8948h,9969h, 0a90ah,0b92bh<br />

60 01A0 F5 5A dw 5af5h, 4ad4h, 7ab7h, 6a96h, 1a71h, 0a50h, 3a33h, 2a12h<br />

61 01B0 FD DB dw 0dbfdh, 0cbdch, 0fbbfh,0eb9eh, 9b79h, 8b58h, 0bb3bh,0ab1ah<br />

62 01C0 A6 6C dw 6ca6h, 7c87h, 4ce4h, 5cc5h, 2c22h, 3c03h,0c60h, 1c41h<br />

63 01D0 AE ED dw 0edaeh, 0fd8fh, 0c<strong>de</strong>ch,0ddcdh, 0ad2ah, 0bd0bh, 8d68h,9d49h<br />

64 01E0 97 7E dw 7e97h, 6eb6h, 5ed5h, 4ef4h, 3e13h, 2e32h, 1e51h, 0e70h<br />

65 01F0 9F FF dw 0ff9fh, 0efbeh, 0dfddh, 0cffch, 0bf1bh, 0af3ah,9f59h,8f78h<br />

66 0200<br />

67 0200 88 91 dw 9188h, 81a9h, 0b1cah,0a1ebh, 0d10ch, 0c12dh, 0f14eh,0e16fh<br />

68 0210 80 10 dw 1080h, 00a1h, 30c2h, 20e3h, 5004h, 4025h, 7046h, 6067h<br />

69 0220 B9 83 dw 83b9h, 9398h,0a3fbh, 0b3dah, 0c33dh, 0d31ch,0e37fh, 0f35eh<br />

70 0230 B1 02 dw 02b1h, 1290h, 22f3h, 32d2h, 4235h, 5214h, 6277h, 7256h<br />

71 0240 EA B5 dw 0b5eah,0a5cbh, 95a8h, 8589h, 0f56eh, 0e54fh, 0d52ch,0c50dh<br />

72 0250 E2 34 dw 34e2h, 24c3h, 14a0h, 0481h, 7466h, 6447h, 5424h, 4405h<br />

73 0260 DB A7 dw 0a7dbh, 0b7fah,8799h, 97b8h, 0e75fh, 0f77eh, 0c71dh,0d73ch<br />

74 0270 D3 26 dw 26d3h, 36f2h, 0691h, 16b0h, 6657h, 7676h, 4615h, 5634h<br />

75 0280 4C D9 dw 0d94ch, 0c96dh, 0f90eh,0e92fh, 99c8h, 89e9h, 0b98ah,0a9abh<br />

76 0290 44 58 dw 5844h, 4865h, 7806h, 6827h, 18c0h, 08e1h, 3882h, 28a3h<br />

77 02A0 7D CB dw 0cb7dh, 0db5ch,0eb3fh, 0fb1eh, 8bf9h, 9bd8h, 0abbbh,0bb9ah<br />

78 02B0 75 4A dw 4a75h, 5a54h, 6a37h, 7a16h, 0af1h, 1ad0h, 2ab3h, 3a92h<br />

79 02C0 2E FD dw 0fd2eh, 0ed0fh, 0dd6ch,0cd4dh, 0bdaah,0ad8bh, 9<strong>de</strong>8h,8dc9h<br />

80 02D0 26 7C dw 7c26h, 6c07h, 5c64h, 4c45h, 3ca2h, 2c83h, 1ce0h, 0cc1h<br />

81 02E0 1F EF dw 0ef1fh, 0ff3eh,0cf5dh, 0df7ch, 0af9bh, 0bfbah, 8fd9h,9ff8h<br />

82 02F0 17 6E dw 6e17h, 7e36h, 4e55h, 5e74h, 2e93h, 3eb2h, 0ed1h, 1ef0h<br />

83 0300 ; Nota: Memoria en formato Intel( parte alta en direccion alta)<br />

Ejemplo 5. Solución <strong>de</strong> un circuito combinatorio con saltos condicionales.<br />

1 0000 ; Resuelve una funcion logica <strong>de</strong> seis variables booleanas<br />

2 0000 ;Q =U *(V + W))+(X * /Y)+/Z don<strong>de</strong> / = negacion logica * = AND<br />

3 0000 U bit P1.1<br />

4 0000 V bit P1.2<br />

5 0000 W bit TF0<br />

6 0000 X bit IE1<br />

7 0000 Y BIT 20h.7<br />

8 0000 Z BIT 20h.6<br />

9 0000 Q bit P3.1 ; salida<br />

10 0000 org 0<br />

11 0000 8036 sjmp 38h<br />

12 0038 org 38h<br />

13 0038<br />

14 0038 209203 Pba_V: jb V,Pba_U<br />

15 003B 308D03 jnb W,Pba_X ; brinca si salida <strong>de</strong> la comp OR = "0"<br />

16 003E 20910D Pba_U: jb U,Q1 ; brinca si salida <strong>de</strong> la AND izq.= "1"<br />

Profr. Salvador Saucedo 19


17 0041 308B03 Pba_X: jnb X,Pba_Z ; si X = 0, probar Z<br />

18 0044 300707 jnb Y,Q1 ;brinca si salida <strong>de</strong> 2da comp. AND="1"<br />

19 0047<br />

20 0047 300604 Pba_Z: jnb Z,Q1 ; incluye ultima variable<br />

21 004A C2B1 clr Q<br />

22 004C 8002 sjmp sigue<br />

23 004E D2B1 Q1: setb Q<br />

24 0050 00 sigue: nop ; el programa continua...<br />

25 0051<br />

PROBLEMAS<br />

1. Cuál es el sesgo relativo <strong>de</strong> la instrucción.<br />

SJMP ALFA<br />

Si la instrucción está en las localida<strong>de</strong>s 1050H y 1051H y la etiqueta ALFA está<br />

representando la instrucción en la localidad 0FF2H?<br />

2. Suponer que la instrucción<br />

AJMP BETA<br />

Está en la memoria <strong>de</strong> código en las localida<strong>de</strong>s 3FE0H y 3FE1H y que la etiqueta BETA<br />

correspon<strong>de</strong> a la instrucción en la dirección 3EE0H. ¿Cuáles son los dos bytes en HEX para<br />

ensamblar esta instrucción (Direccionamiento absoluto)<br />

3. En cierto punto <strong>de</strong>l programa se <strong>de</strong>sea brincar a la etiqueta FINAL si el valor en el<br />

acumulador es igual al ASCII <strong>de</strong>l carácter EOT (fin <strong>de</strong> texto). Qué instrucción(es) usar?<br />

4. La instrucción:<br />

SETB 0D7H<br />

¿Qué hace?, ¿Cómo pue<strong>de</strong> hacerse lo mismo pero más rápido?<br />

5. ¿Cuáles son las diferencias entre las dos <strong>instrucciones</strong>?<br />

INC A<br />

ADD A, #1<br />

6. Cuáles son los bytes para ensamblar la instrucción<br />

LJMP LEJOS<br />

Si la etiqueta LEJOS representa la instrucción situada en la localidad 7C22H?<br />

7. Suponer que el acumulador A contiene 0F3H. ¿Qué valor queda en A si se ejecuta la<br />

instrucción siguiente?<br />

XRL A, #45H<br />

8. Suponer que el registro PSW tiene 81H y el acumulador A contiene 02DH antes que se<br />

ejecute la instrucción<br />

Profr. Salvador Saucedo 20


RLC A<br />

¿Cuánto valen PSW y A tras la ejecución <strong>de</strong> la misma?<br />

9. Mencionar y explicar los modos <strong>de</strong> direccionamiento: directo, inmediato, relativo e<br />

in<strong>de</strong>xado, dando dos ejemplos <strong>de</strong> cada uno.<br />

10. Cuál secuencia <strong>de</strong> <strong>instrucciones</strong> pue<strong>de</strong> usarse para generar un pulso en alto en P1.7 <strong>de</strong><br />

6.51 μs <strong>de</strong> duración, asumiendo que P1.7 está inicialmente en 0? Y que el cristal es <strong>de</strong><br />

11.0592 MHz.<br />

11. Escribir un programa para generar una onda cuadrada en P1.0 <strong>de</strong> 76.77 kHz con el cristal<br />

<strong>de</strong> 11.0592 MHz.<br />

12. Escribir un programa empleando <strong>instrucciones</strong> booleanas para implementar la ecuación<br />

combinatoria dada.<br />

Cuál es el peor tiempo <strong>de</strong> transición <strong>de</strong>l cambio en alguna <strong>de</strong> las entradas?<br />

13. Cuántas <strong>instrucciones</strong> <strong>de</strong> 1 byte son?. Y <strong>de</strong> tres bytes?<br />

14. Cuáles <strong>instrucciones</strong> pue<strong>de</strong>n afectar a la ban<strong>de</strong>ra <strong>de</strong> acarreo?.<br />

15. Cuál es el contenido <strong>de</strong>l acumulador tras la siguiente secuencia <strong>de</strong> <strong>instrucciones</strong><br />

MOV A, #7DH<br />

MOV 46H, #97H<br />

MOV R1, #46H<br />

XCHD A,@R1<br />

16. Dar la secuencia que copie la ban<strong>de</strong>ra F0 <strong>de</strong>l PSW en la terminal P1.5<br />

17. La RAM interna está inicializada como sigue (HEX) justo antes <strong>de</strong> ejecutar la<br />

instrucción RET:<br />

Localidad interna Contenido SFRs Contenido<br />

6B 5C SP 6A<br />

6A 23 PC 1340<br />

69 56 A 55<br />

68 34 PSW 80<br />

67 78<br />

Cuál es el valor en el contador <strong>de</strong> programa PC y <strong>de</strong>l SP tras que RET se ejecuta?<br />

18. Se muestra una subrutina para el 8031<br />

SUB: MOV R0,#30H<br />

LAZO: MOV @R0, #-1<br />

INC R0<br />

CJNE R0, #50H, LAZO<br />

RET<br />

A) Qué hace la subrutina?.<br />

Profr. Salvador Saucedo 21


B) Cuántos ciclos <strong>de</strong> máquina toma?.<br />

C) Cuántos bytes mi<strong>de</strong> cada instrucción?.<br />

D) Convertir la subrutina a lenguaje <strong>de</strong> máquina.<br />

E) Dado el valor <strong>de</strong>l cristal <strong>de</strong> 11.0592 MHz, cuánto tiempo toma?<br />

19. Cuál instrucción tiene el código 5DH? Y cuál para el código FFH? Y el 00?<br />

20. Cuál es el código <strong>de</strong> operación para la instrucción INC DPTR? Y para la instrucción<br />

DEC R0? Y para CLR C?<br />

21. Calcular CRC <strong>de</strong> la ca<strong>de</strong>na ASCIIZ: ‘Mal’,0.<br />

22. Un dip switch <strong>de</strong> 4 bits se conecta a un 8031 el que a su vez se conecta a un buffer que<br />

maneja un módulo <strong>de</strong> ánodo común <strong>de</strong> siete segmentos. Hacer el programa (o rutina) que<br />

exhiba el estado <strong>de</strong> los switches en el display. Por ejemplo un 0110B <strong>de</strong>berá exhibir el<br />

numeral 6 (lo que más parezca) y así con las <strong>de</strong>más combinaciones. Ver esquema.<br />

Profr. Salvador Saucedo 22


Apéndice A Instrucciones: Código, Nemotécnico, Num. De Bytes, Ciclos y Modos <strong>de</strong> Direccionamiento<br />

Nible<br />

bajo ↓<br />

alto→ 0 1 2 3 4 5<br />

1 1 3 2 3 2 3 2 2 2 2 2<br />

0<br />

NOP<br />

JBC<br />

JB<br />

JNB<br />

JC<br />

JNC<br />

DirBit,DirCod DirBit,DirCod DirBit,DirCod DirCodigo DirCodigo<br />

2 2 2 2 2 2 2 2 2 2 2 2<br />

1<br />

AJMP ACALL AJMP ACALL AJMP ACALL<br />

DirCodigo DirCodigo DirCodigo DirCodigo DirCodigo DirCodigo<br />

3 2 3 2 1 2 1 2 2 2 2 2<br />

2<br />

LJMP LCALL<br />

RET<br />

RETI<br />

ORL<br />

ANL<br />

DirCodigo DirCodigo<br />

DirDato, A DirDato, A<br />

1 1 1 1 1 1 1 1 3 2 3 2<br />

3<br />

RR<br />

RRC<br />

RL<br />

RLC<br />

ORL<br />

ANL<br />

A<br />

A<br />

A<br />

A DirDato,#dato DirDato,#dato<br />

1 1 1 1 2 1 2 1 2 1 2 1<br />

4<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

A<br />

A<br />

A, #dato A, #dato A, #dato A, #dato<br />

2 1 2 1 2 1 2 1 2 1 2 1<br />

5<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

DirDato DirDato A, DirDato A, DirDato A, DirDato A, DirDato<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

6<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

@R0<br />

@R0 A, @R0 A, @R0 A, @R0 A, @R0<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

7<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

@R1<br />

@R1 A, @R1 A, @R1 A, @R1 A, @R1<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

8<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R0<br />

R0<br />

A, R0<br />

A, R0<br />

A, R0<br />

A, R0<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

9<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R1<br />

R1<br />

A, R1<br />

A, R1<br />

A, R1<br />

A, R1<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

A<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R2<br />

R2<br />

A, R2<br />

A, R2<br />

A, R2<br />

A, R2<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

B<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R3<br />

R3<br />

A, R3<br />

A, R3<br />

A, R3<br />

A, R3<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

C<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R4<br />

R4<br />

A, R4<br />

A, R4<br />

A, R4<br />

A, R4<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

D<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R5<br />

R5<br />

A, R5<br />

A, R5<br />

A, R5<br />

A, R5<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

E<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R6<br />

R6<br />

A, R6<br />

A, R6<br />

A, R6<br />

A, R6<br />

1 1 1 1 1 1 1 1 1 1 1 1<br />

F<br />

INC<br />

DEC<br />

ADD<br />

ADDC<br />

ORL<br />

ANL<br />

R7<br />

R7<br />

A, R7<br />

A, R7<br />

A, R7<br />

A, R7<br />

b c b = Número <strong>de</strong> bytes; c = número <strong>de</strong> ciclos<br />

Clave: nem<br />

oper<br />

nem = Nemotécnico; oper = Operando(s)<br />

Profr. Salvador Saucedo 23


Apéndice A Instrucciones: Código, Nemotécnico, Num. De Bytes, Ciclos y Modos <strong>de</strong> Direccionamiento<br />

Nibles<br />

bajo ↓<br />

alto→ 6 7 8 9 A B<br />

2 2 2 2 2 2 3 2 2 2 2 2<br />

0<br />

JZ<br />

JNZ<br />

SJMP<br />

MOV<br />

ORL<br />

ANL<br />

DirCodigo DirCodigo DirBit,DirCod DPTR,#dato C, /DirBit C, /DirBit<br />

2 2 2 2 2 2 2 2 2 2 2 2<br />

1<br />

AJMP ACALL AJMP ACALL AJMP ACALL<br />

DirCodigo DirCodigo DirCodigo DirCodigo DirCodigo DirCodigo<br />

2 2 2 2 2 2 2 2 2 2 2 1<br />

2<br />

XRL<br />

ORL<br />

ANL<br />

MOV<br />

ORL<br />

CPL<br />

DirDato, A C, DirBit C, DirBit DirBit, C C, DirBit DirBit<br />

3 2 1 2 1 2 1 2 1 1 1 1<br />

3<br />

XRL<br />

JMP<br />

MOVC MOVC<br />

INC<br />

CPL<br />

DirDato, #dato @A+DPTR A,@A+PC A,@A+DPTR DPTR<br />

C<br />

2 1 2 1 1 4 2 1 1 4 3 2<br />

4<br />

XRL<br />

MOV<br />

DIV<br />

SUBB<br />

MUL<br />

CJNE<br />

A,#dato A, #dato<br />

AB<br />

A, #dato<br />

AB A, #dato,DirCod<br />

2 1 3 2 3 2 2 1<br />

3 2<br />

5<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

CJNE<br />

A,DirDato DirDato, #dato DirDato,DirDat A, DirDato<br />

A,DirDato,DirCo<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

6<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, @R0 @R0,#dato DirDato, @R0 A, @R0 @R0,DirDato @R0,#da,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

7<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, @R1 @R1,#dato DirDato, @R1 A, @R1 @R1,DirDato @R1,#da,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

8<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R0 R0,#dato DirDato, R0 A, R0 R0, DirDato R0,#dato,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

9<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R1 R1,#dato DirDato, R1 A, R1 R1, DirDato R1,#dato,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

A<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R2 R2,#dato DirDato, R2 A, R2 R2, DirDato R2,#dato,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

B<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R3 R3,#dato DirDato, R3 A, R3 R3, DirDato R3,#dato,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

C<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R4 R4,#dato DirDato, R4 A, R4 R4, DirDato R4,#dato,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

D<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R5 R5,#dato DirDato, R5 A, R5 R5, DirDato R5,#dato,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

E<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R6 R6,#dato DirDato, R6 A, R6 R6, DirDato R6,#dato,DirCod<br />

1 1 2 1 2 2 1 1 2 2 3 2<br />

F<br />

XRL<br />

MOV<br />

MOV<br />

SUBB<br />

MOV<br />

CJNE<br />

A, R7 R7,#dato DirDato, R7 A, R7 R7, DirDato R7,#dato,DirCod<br />

b c b = Número <strong>de</strong> bytes; c = número <strong>de</strong> ciclos<br />

Clave: nem<br />

oper<br />

nem = Nemotécnico; oper = Operando(s)<br />

Profr. Salvador Saucedo 24


Apéndice A Instrucciones: Código, Nemotécnico, Num. De Bytes, Ciclos y Modos <strong>de</strong> Direccionamiento<br />

Nibles<br />

bajo ↓<br />

alto→ C D E F9<br />

2 2 2 2 1 2 1 2<br />

0<br />

PUSH<br />

POP<br />

MOVX MOVX<br />

DirDato DirDato A,@DPTR @DPTR,A<br />

2 2 2 2 2 2 2 2<br />

1<br />

AJMP ACALL AJMP ACALL<br />

DirCodigo DirCodigo DirCodigo DirCodigo<br />

2 2 2 2 1 2 1 2<br />

2<br />

CLR<br />

SETB MOVX MOVX<br />

DirBit<br />

DirBit A, @R0 @R0, A<br />

1 2 1 2 1 2 1 2<br />

3<br />

CLR<br />

SETB MOVX MOVX<br />

C<br />

C<br />

A, @R1 @R1, A<br />

1 1 1 1 1 1 1 1<br />

4 SWAP<br />

DA<br />

CLR<br />

CPL<br />

A<br />

A<br />

A<br />

A<br />

2 1 3 2 2 2 2 1<br />

5<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A,DirDato DirDato,DirCod A,DirDato DirDato, A<br />

1 1 1 1 1 1 1 1<br />

6<br />

XCH<br />

XCHD<br />

MOV<br />

MOV<br />

A, @R0 A, @R0 A, @R0 @R0, A<br />

1 1 1 1 1 1 1 1<br />

7<br />

XCH<br />

XCHD<br />

MOV<br />

MOV<br />

A, @R1 A, @R1 A, @R1 @R1, A<br />

1 1 2 2 1 1 1 1<br />

8<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R0 R0, DirCodigo A, R0<br />

R0, A<br />

1 1 2 2 1 1 1 1<br />

9<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R1 R1, DirCodigo A, R1<br />

R1, A<br />

1 1 2 2 1 1 1 1<br />

A<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R2 R2, DirCodigo A, R2<br />

R2, A<br />

1 1 2 2 1 1 1 1<br />

B<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R3 R3, DirCodigo A, R3<br />

R3, A<br />

1 1 2 2 1 1 1 1<br />

C<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R4 R4, DirCodigo A, R4<br />

R4, A<br />

1 1 2 2 1 1 1 1<br />

D<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R5 R5, DirCodigo A, R5<br />

R5, A<br />

1 1 2 2 1 1 1 1<br />

E<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R6 R6, DirCodigo A, R6<br />

R6, A<br />

1 1 2 2 1 1 1 1<br />

F<br />

XCH<br />

DJNZ<br />

MOV<br />

MOV<br />

A, R7 R7, DirCodigo A, R7<br />

R7, A<br />

b c b = Número <strong>de</strong> bytes; c = número <strong>de</strong> ciclos<br />

Clave: nem<br />

oper<br />

nem = Nemotécnico; oper = Operando(s)<br />

Profr. Salvador Saucedo 25

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!