08.05.2013 Views

Juego de instrucciones del 80C31

Juego de instrucciones del 80C31

Juego de instrucciones del 80C31

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

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!