Juego de instrucciones del 80C31
Juego de instrucciones del 80C31
Juego de instrucciones del 80C31
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