Sistemas integrados: instrucciones
El flujo del programa procede de manera secuencial, de una instrucción a la siguiente, a menos que se ejecute una instrucción de transferencia de control. Los diversos tipos de instrucciones de transferencia de control en lenguaje ensamblador incluyen saltos condicionales o incondicionales e instrucciones de llamada.
Instrucciones de bucle y salto
Bucle en el 8051
Repetir una secuencia de instrucciones un cierto número de veces se denomina loop. Una instrucciónDJNZ reg, labelse utiliza para realizar una operación de bucle. En esta instrucción, un registro se reduce en 1; si no es cero, 8051 salta a la dirección de destino a la que hace referencia la etiqueta.
El registro se carga con el contador del número de repeticiones antes del inicio del ciclo. En esta instrucción, tanto el decremento de registros como la decisión de saltar se combinan en una sola instrucción. Los registros pueden ser cualquiera de R0 – R7. El contador también puede ser una ubicación de RAM.
Ejemplo
Multiply 25 by 10 using the technique of repeated addition.
Solution- La multiplicación se puede lograr sumando el multiplicando repetidamente, tantas veces como el multiplicador. Por ejemplo,
25 * 10 = 250 (FAH)
25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 = 250
MOV A,#0 ;A = 0,clean ACC
MOV R2,#10 ; the multiplier is replaced in R2
Add A,#25 ;add the multiplicand to the ACC
AGAIN:DJNZ R2,
AGAIN:repeat until R2 = 0 (10 times)
MOV R5 , A ;save A in R5 ;R5 (FAH)
Drawback in 8051 - Acción de bucle con la instrucción DJNZ Reg labelestá limitado a 256 iteraciones únicamente. Si no se realiza un salto condicional, se ejecuta la instrucción que sigue al salto.
Bucle dentro de un bucle
Cuando usamos un bucle dentro de otro bucle, se llama nested loop. Se usan dos registros para mantener el conteo cuando el conteo máximo está limitado a 256. Por lo tanto, usamos este método para repetir la acción más de 256 veces.
Example
Escribe un programa para -
- Cargue el acumulador con el valor 55H.
- Complementa el ACC 700 veces.
Solution- Dado que 700 es mayor que 255 (la capacidad máxima de cualquier registro), se utilizan dos registros para mantener la cuenta. El siguiente código muestra cómo utilizar dos registros, R2 y R3, para el recuento.
MOV A,#55H ;A = 55H
NEXT: MOV R3,#10 ;R3 the outer loop counter
AGAIN:MOV R2,#70 ;R2 the inner loop counter
CPL A ;complement
Otros saltos condicionales
La siguiente tabla enumera los saltos condicionales utilizados en 8051 -
Instrucción | Acción |
---|---|
JZ | Saltar si A = 0 |
JNZ | Saltar si A ≠ 0 |
DJNZ | Decrementar y saltar si el registro ≠ 0 |
CJNE A, datos | Saltar si A ≠ datos |
CJNE reg, #data | Saltar si byte ≠ datos |
JC | Saltar si CY = 1 |
JNC | Saltar si CY ≠ 1 |
JB | Saltar si bit = 1 |
JNB | Saltar si bit = 0 |
JBC | Saltar si bit = 1 y borrar bit |
JZ (jump if A = 0)- En esta instrucción, se verifica el contenido del acumulador. Si es cero, el 8051 salta a la dirección de destino. La instrucción JZ se puede usar solo para el acumulador, no se aplica a ningún otro registro.
JNZ (jump if A is not equal to 0)- En esta instrucción, se comprueba que el contenido del acumulador sea distinto de cero. Si no es cero, el 8051 salta a la dirección de destino.
JNC (Jump if no carry, jumps if CY = 0)- El bit de bandera de acarreo en el registro de bandera (o PSW) se utiliza para tomar la decisión de saltar o no la "etiqueta JNC". La CPU mira la bandera de acarreo para ver si está levantada (CY = 1). Si no se genera, la CPU comienza a buscar y ejecutar instrucciones desde la dirección de la etiqueta. Si CY = 1, no saltará pero ejecutará la siguiente instrucción debajo de JNC.
JC (Jump if carry, jumps if CY = 1) - Si CY = 1, salta a la dirección de destino.
JB (jump if bit is high)
JNB (jump if bit is low)
Note - Debe tenerse en cuenta que todos los saltos condicionales son saltos cortos, es decir, la dirección del objetivo debe estar entre –128 y +127 bytes del contenido del contador del programa.
Instrucciones de salto incondicional
Hay dos saltos incondicionales en 8051 -
LJMP (long jump)- LJMP es una instrucción de 3 bytes en la que el primer byte representa el código de operación y el segundo y tercer bytes representan la dirección de 16 bits de la ubicación de destino. La dirección de destino de 2 bytes permite un salto a cualquier ubicación de memoria desde 0000 a FFFFH.
SJMP (short jump)- Es una instrucción de 2 bytes donde el primer byte es el código de operación y el segundo byte es la dirección relativa de la ubicación de destino. La dirección relativa varía de 00H a FFH, que se divide en saltos hacia adelante y hacia atrás; es decir, entre –128 y +127 bytes de memoria en relación con la dirección de la PC actual (contador de programa). En caso de salto hacia adelante, la dirección de destino puede estar dentro de un espacio de 127 bytes desde la PC actual. En caso de salto hacia atrás, la dirección de destino puede estar dentro de los –128 bytes de la PC actual.
Cálculo de la dirección de salto corto
Todos los saltos condicionales (JNC, JZ y DJNZ) son saltos cortos porque son instrucciones de 2 bytes. En estas instrucciones, el primer byte representa el código de operación y el segundo byte representa la dirección relativa. La dirección de destino siempre es relativa al valor del contador del programa. Para calcular la dirección de destino, el segundo byte se agrega a la PC de la instrucción inmediatamente debajo del salto. Eche un vistazo al programa que se muestra a continuación:
Line PC Op-code Mnemonic Operand
1 0000 ORG 0000
2 0000 7800 MOV R0,#003
3 0002 7455 MOV A,#55H0
4 0004 6003 JZ NEXT
5 0006 08 INC R0
6 0007 04 AGAIN: INC A
7 0008 04 INC A
8 0009 2477 NEXT: ADD A, #77h
9 000B 5005 JNC OVER
10 000D E4 CLR A
11 000E F8 MOV R0, A
12 000F F9 MOV R1, A
13 0010 FA MOV R2, A
14 0011 FB MOV R3, A
15 0012 2B OVER: ADD A, R3
16 0013 50F2 JNC AGAIN
17 0015 80FE HERE: SJMP HERE
18 0017 END
Cálculo de dirección de destino de salto hacia atrás
En caso de un salto hacia adelante, el valor de desplazamiento es un número positivo entre 0 y 127 (00 a 7F en hexadecimal). Sin embargo, para un salto hacia atrás, el desplazamiento es un valor negativo de 0 a –128.
Instrucciones de LLAMADA
CALL se usa para llamar a una subrutina o método. Las subrutinas se utilizan para realizar operaciones o tareas que deben realizarse con frecuencia. Esto hace que un programa sea más estructurado y ahorra espacio en la memoria. Hay dos instrucciones: LCALL y ACALL.
LCALL (llamada larga)
LCALL es una instrucción de 3 bytes donde el primer byte representa el código de operación y el segundo y tercer bytes se utilizan para proporcionar la dirección de la subrutina de destino. LCALL se puede utilizar para llamar subrutinas que están disponibles dentro del espacio de direcciones de 64K bytes del 8051.
Para hacer un regreso exitoso al punto después de la ejecución de la subrutina llamada, la CPU guarda la dirección de la instrucción inmediatamente debajo de LCALL en la pila. Por lo tanto, cuando se llama a una subrutina, el control se transfiere a esa subrutina y el procesador guarda la PC (contador de programa) en la pila y comienza a buscar instrucciones desde la nueva ubicación. La instrucción RET (retorno) transfiere el control de nuevo al llamador después de finalizar la ejecución de la subrutina. Cada subrutina usa RET como última instrucción.
ACALL (Absolute Call)
ACALL es una instrucción de 2 bytes, en contraste con LCALL, que tiene 3 bytes. La dirección de destino de la subrutina debe estar dentro de los 2K bytes porque solo se usan 11 bits de los 2 bytes para la dirección. La diferencia entre ACALL y LCALL es que la dirección de destino para LCALL puede estar en cualquier lugar dentro del espacio de direcciones de 64K bytes del 8051, mientras que la dirección de destino de CALL está dentro de un rango de 2K bytes.