Ingeniería inversa de MCU

Desbloqueo de microcontroladores - MikaTech

Nuestros valores y objetivos

Sobre MikaTech

El tiempo pasó rápido: desde el día en que realizamos nuestro primer proyecto de ingeniería inversa de MCU 8051 en 1998, hasta el día en que fundamos nuestro laboratorio de ingeniería inversa de un millón de dólares en 2012, transcurrieron 14 años. Ahora iniciamos nuestro nuevo negocio de desarrollo de sistemas visuales integrados; esperamos poder servir otros 10 años más.

firma Peter Lee Cofundador y CEO

Arquitectura y programación de MCU 8051 para ingeniería inversa 2

Capítulo 3: El conjunto de instrucciones del 8051

Introducción

Escribir programas para microcontroladores consiste principalmente en emitir instrucciones (comandos) en una secuencia de ejecución específica para completar las tareas designadas. El hardware electrónico no puede interpretar lógica legible por humanos, como "si se pulsa el pulsador, enciende la luz". En su lugar, los desarrolladores deben usar una serie de comandos simples y estrictamente definidos reconocibles por el decodificador interno del MCU. El conjunto completo de estos comandos válidos se conoce como conjunto de instrucciones. Todos los microcontroladores compatibles con 8051 cuentan con un total de 255 instrucciones distintas, lo que significa que hay 255 palabras de máquina únicas disponibles para el desarrollo de programas.

At first glance, memorizing this large set of symbolic opcodes seems intimidating. However, the actual learning burden is far lighter than it appears. Many instructions count as separate entries even though they execute identical underlying operations, leaving only 111 functionally unique commands. For example, ADD A,R0, ADD A,R1, ..., ADD A,R7 all perform the same addition operation between the accumulator and a working register. Since there are eight working registers, each variant is listed as a separate instruction entry. Considering that all instructions only implement 53 core operations (addition, subtraction, data copy, etc.) and most of these operations are rarely used in practical projects, developers only need to master roughly 20 to 30 mnemonics — a very manageable amount.

Más allá de la ejecución funcional del programa, el conjunto de instrucciones forma la primera línea de defensa contra el acceso no autorizado al firmware. La mayoría de los sistemas embebidos dependen de mecanismos de bit de bloqueo para impedir la lectura externa de la memoria flash o EEPROM interna. No obstante, una comprensión profunda del comportamiento en tiempo de ejecución de cada instrucción es esencial tanto para escribir firmware de producción seguro como para realizar ingeniería inversa legítima y recuperar el código fuente perdido. Los atacantes explotan con frecuencia comportamientos específicos de las instrucciones para eludir la protección de bloqueo, aprovechando la inyección de fallos, el análisis de temporización y otras técnicas de canal lateral para desencadenar un estado de desbloqueo. En muchos escenarios de ataque, la decapsulación física del chip junto con la microsonda lee directamente los bits de estado de los fusibles, permitiendo volcados binarios completos del firmware almacenado. La capacidad de replicar la funcionalidad completa de un dispositivo depende a menudo del éxito de la extracción de firmware mediante estos métodos, lo que convierte la recuperación de firmware en una habilidad crítica dentro de la investigación de seguridad embebida.

3.1 Tipos de instrucciones

Todas las instrucciones se clasifican en cinco grupos centrales según las operaciones que realizan:

  • Instrucciones aritméticas
  • Instrucciones de bifurcación
  • Instrucciones de transferencia de datos
  • Instrucciones lógicas
  • Instrucciones orientadas a bits

El primer segmento de cada instrucción se llama mnemónico, que representa la operación central a ejecutar (copia de datos, suma aritmética, lógica bit a bit, etc.). Los mnemónicos son abreviaturas cortas del nombre completo de cada operación de hardware. A continuación se muestran definiciones de ejemplo:

  • INC R1 – Increment the value stored in register R1 by one;
  • LJMP LAB5 – Perform a long unconditional jump to the memory address labeled LAB5;
  • JNZ LOOP – Jump to the address labeled LOOP if the accumulator value is non-zero;

El segundo segmento de una instrucción es el operando, separado del mnemónico por al menos un carácter de espacio en blanco, y define los objetivos de datos procesados por la operación. Algunas instrucciones no llevan operandos, mientras que otras incluyen uno, dos o tres operandos. Los múltiples operandos dentro de una sola instrucción se separan con comas. Ejemplos:

  • RET – Return execution flow from a subroutine;
  • JZ TEMP – Jump to the address labeled TEMP if the accumulator value equals zero;
  • ADD A,R3 – Add the value of register R3 to the accumulator;
  • CJNE A,#20,LOOP – Compare the accumulator against the immediate constant 20; jump to LOOP if the two values are unequal;

Cada categoría de instrucciones desempeña un papel distinto en la postura de seguridad general del dispositivo. Las instrucciones orientadas a bits manipulan directamente los bits de bloqueo y otros fusibles de configuración de seguridad. Los códigos de operación de transferencia de datos como MOVC leen la memoria de código, y estas instrucciones devuelven datos inválidos alterados cuando la protección de bit de bloqueo está activa. Los flujos de trabajo de ingeniería inversa se centran con frecuencia en identificar las secuencias de instrucciones que validan el estado del bloqueo, para luego intentar omitir estas ramas de validación mediante fluctuaciones de reloj o manipulación del contador de programa. En algunos casos, recuperar un MCU bloqueado e inutilizado requiere localizar puertas traseras ocultas del bootloader que utilizan instrucciones de bifurcación específicas para habilitar la lectura completa de memoria.

Instrucciones aritméticas

Las instrucciones aritméticas ejecutan operaciones matemáticas fundamentales, incluidos la suma, la resta, la multiplicación y la división. Tras completar el cálculo, el valor resultante se almacena dentro del primer operando especificado. Ejemplo:

ADD A,R1 – The sum of accumulator A and register R1 is saved back into the accumulator register.

Instrucciones aritméticas
Mnemónico Descripción Byte Ciclo
ADD A,Rn Sumar el contenido del registro de trabajo al acumulador 1 1
ADD A,direct Sumar el byte de dirección directa al acumulador 2 2
ADD A,@Ri Sumar el byte de RAM interna direccionado indirectamente al acumulador 1 2
ADD A,#data Sumar el valor constante inmediato al acumulador 2 2
ADDC A,Rn Sumar el registro al acumulador con entrada de bandera de acarreo 1 1
ADDC A,direct Sumar el byte directo al acumulador con entrada de bandera de acarreo 2 2
ADDC A,@Ri Sumar el byte de RAM indirecto al acumulador con entrada de bandera de acarreo 1 2
ADDC A,#data Sumar la constante inmediata al acumulador con entrada de bandera de acarreo 2 2
SUBB A,Rn Restar el registro del acumulador con entrada de bandera de préstamo 1 1
SUBB A,direct Restar el byte directo del acumulador con entrada de bandera de préstamo 2 2
SUBB A,@Ri Restar el byte de RAM indirecto del acumulador con entrada de bandera de préstamo 1 2
SUBB A,#data Restar la constante inmediata del acumulador con entrada de bandera de préstamo 2 2
INC A Incrementar el valor del acumulador en uno 1 1
INC Rn Incrementar el valor del registro de trabajo en uno 1 2
INC Rx Incrementar el byte de dirección directa en uno 2 3
INC @Ri Incrementar el byte de RAM direccionado indirectamente en uno 1 3
DEC A Decrementar el valor del acumulador en uno 1 1
DEC Rn Decrementar el valor del registro de trabajo en uno 1 1
DEC Rx Decrementar el byte de dirección directa en uno 1 2
DEC @Ri Decrementar el byte de RAM direccionado indirectamente en uno 2 3
INC DPTR Incrementar el registro puntero de datos de 16 bits en uno 1 3
MUL AB Multiplicar el acumulador A por el registro B 1 5
DIV AB Dividir el acumulador A por el registro B 1 5
DA A Ajuste decimal del acumulador para resultados aritméticos BCD 1 1

Las instrucciones aritméticas sirven para algo más que tareas puras de procesamiento de datos; son parte integral de las rutinas de verificación de suma de comprobación y de cifrado que validan la integridad del firmware. Los atacantes que pueden corromper los resultados de suma o resta mediante fluctuaciones de tensión pueden eludir los controles de seguridad que comparan las sumas de comprobación calculadas con los valores de referencia almacenados. Esta manipulación puede desencadenar una secuencia de desbloqueo incluso cuando el fusible del bit de bloqueo permanece activado. Para los flujos de trabajo de extracción de firmware, un conocimiento profundo del comportamiento aritmético de la ALU permite diseñar ataques dirigidos de inyección de fallos destinados a omitir la lógica de validación del bloqueo. Además, las banderas de estado de acarreo (C) y desbordamiento (OV) son objetivos de ataque frecuentes: provocar fluctuaciones en la unidad aritmético-lógica puede forzar estados de bandera incorrectos y evadir las comprobaciones críticas de comparación del estado de bloqueo.

Instrucciones de bifurcación

Las instrucciones de bifurcación se dividen en dos categorías distintas:

Instrucciones de salto incondicional: al ejecutarse, la CPU salta de inmediato a una nueva dirección de memoria y reanuda el flujo del programa desde esa ubicación sin condiciones previas.

Instrucciones de salto condicional: un salto a una dirección de programa alternativa solo se ejecuta si una condición lógica especificada se evalúa como verdadera. Si la condición falla, la CPU procede secuencialmente a la siguiente instrucción en memoria.

Instrucciones de bifurcación
Mnemónico Descripción Byte Ciclo
ACALL addr11 Llamada absoluta a subrutina de página de 2KB 2 6
LCALL addr16 Llamada larga a subrutina de 64KB de dirección completa 3 6
RET Retorno de la ejecución desde una subrutina estándar 1 4
RETI Retorno de la ejecución desde la rutina de servicio de interrupción 1 4
AJMP addr11 Salto absoluto dentro de la página de memoria actual de 2KB 2 3
LJMP addr16 Salto largo a cualquier dirección de memoria de programa de 64KB 3 4
SJMP rel Salto relativo corto (desplazamiento de -128 a +127 desde la siguiente instrucción) 2 3
JC rel Salto corto si la bandera de acarreo C está activada 2 3
JNC rel Salto corto si la bandera de acarreo C está desactivada 2 3
JB bit,rel Salto corto si el bit directo especificado es un 1 lógico 3 4
JBC bit,rel Saltar si el bit directo está activado y luego limpiar el bit objetivo (salto corto) 3 4
JMP @A+DPTR Salto indexado indirecto usando el acumulador + desplazamiento del puntero de datos 1 2
JZ rel Salto corto si el acumulador es igual a cero 2 3
JNZ rel Salto corto si el acumulador contiene un valor distinto de cero 2 3
CJNE A,direct,rel Comparar el acumulador y el byte directo; salto corto si los valores son desiguales 3 4
CJNE A,#data,rel Comparar el acumulador y la constante inmediata; salto corto si son desiguales 3 4
CJNE Rn,#data,rel Comparar el registro de trabajo y la constante inmediata; salto corto si son desiguales 3 4
CJNE @Ri,#data,rel Comparar el byte de RAM indirecto y la constante; salto corto si son desiguales 3 4
DJNZ Rn,rel Decrementar el registro, salto corto si el resultado es distinto de cero 2 3
DJNZ Rx,rel Decrementar el byte directo, salto corto si el resultado es distinto de cero 3 4
NOP Sin operación (marcador de retardo de ciclo de reloj) 1 1

Las instrucciones de bifurcación forman el núcleo de la lógica condicional del programa, incluidas todas las rutinas críticas de validación de seguridad. El código de operación JB, por ejemplo, se despliega ampliamente para comprobar el estado del fusible del bit de bloqueo. Si el bit de bloqueo está activado, el programa salta a una subrutina de seguridad que deshabilita las interfaces de depuración y bloquea la lectura de memoria. Los atacantes pueden atacar la ejecución de la instrucción JB con fluctuaciones de reloj para forzar al hardware a tratar un bit de bloqueo activado como desactivado, desbloqueando por completo el microcontrolador. De manera similar, las instrucciones CJNE alimentan los bucles de verificación de contraseñas; inyectar un fallo de temporización o tensión en medio de la comparación puede redirigir el contador de programa a una dirección no intencionada, exponiendo el código de firmware protegido. Dentro de los flujos de trabajo de ingeniería inversa, mapear el grafo completo del flujo de control de bifurcaciones es obligatorio para localizar rutas de desbloqueo legítimas y parchear el firmware binario para la recuperación de datos.

Instrucciones de transferencia de datos

Los códigos de operación de transferencia de datos copian valores de un registro o ubicación de memoria a otro, dejando los datos de origen sin modificar. Las instrucciones que llevan el sufijo "X" (MOVX) facilitan el intercambio de datos con los espacios de memoria RAM externa.

Instrucciones de transferencia de datos
Mnemónico Descripción Byte Ciclo
MOV A,Rn Copiar el valor del registro de trabajo al acumulador 1 1
MOV A,direct Copiar el byte de dirección directa al acumulador 2 2
MOV A,@Ri Copiar el byte de RAM interna direccionado indirectamente al acumulador 1 2
MOV A,#data Cargar el valor constante inmediato en el acumulador 2 2
MOV Rn,A Copiar el valor del acumulador al registro de trabajo 1 2
MOV Rn,direct Copiar el byte de dirección directa al registro de trabajo 2 4
MOV Rn,#data Cargar la constante inmediata en el registro de trabajo 2 2
MOV direct,A Copiar el valor del acumulador al byte de dirección directa 2 3
MOV direct,Rn Copiar el valor del registro de trabajo al byte de dirección directa 2 3
MOV direct,direct Copiar un byte de dirección directa a otra ubicación directa 3 4
MOV direct,@Ri Copiar el byte de RAM indirecto al byte de dirección directa 2 4
MOV direct,#data Cargar la constante inmediata en el byte de dirección directa 3 3
MOV @Ri,A Copiar el valor del acumulador al byte de RAM direccionado indirectamente 1 3
MOV @Ri,direct Copiar el byte de dirección directa a la ubicación de RAM indirecta 2 5
MOV @Ri,#data Cargar la constante inmediata en el byte de RAM indirecto 2 3
MOV DPTR,#data Cargar la constante inmediata de 16 bits en el registro puntero de datos 3 3
MOVC A,@A+DPTR Leer el byte de memoria de código en el desplazamiento A+DPTR al acumulador 1 3
MOVC A,@A+PC Leer el byte de memoria de código en el desplazamiento A+PC al acumulador 1 3
MOVX A,@Ri Leer el byte de RAM externa direccionada de 8 bits al acumulador 1 3-10
MOVX A,@DPTR Leer el byte de RAM externa direccionada de 16 bits al acumulador 1 3-10
MOVX @Ri,A Escribir el valor del acumulador en la dirección de RAM externa de 8 bits 1 4-11
MOVX @DPTR,A Escribir el valor del acumulador en la dirección de RAM externa de 16 bits 1 4-11
PUSH direct Empujar el byte de dirección directa a la pila del sistema 2 4
POP direct Extraer el valor superior de la pila al byte de dirección directa 2 3
XCH A,Rn Intercambiar los valores completos de byte entre el acumulador y el registro de trabajo 1 2
XCH A,direct Intercambiar los valores completos de byte entre el acumulador y el byte directo 2 3
XCH A,@Ri Intercambiar los valores completos de byte entre el acumulador y el byte de RAM indirecto 1 3
XCHD A,@Ri Intercambiar solo el nibble inferior de 4 bits del acumulador y el byte de RAM indirecto 1 3

Las instrucciones de transferencia de datos aparecen con mayor frecuencia en todo el firmware embebido y, al mismo tiempo, representan superficies de ataque críticas para las explotaciones de seguridad. Los códigos de operación MOVC están diseñados exclusivamente para leer la memoria de código del programa; cuando la protección de bit de bloqueo está activa, estas instrucciones devuelven datos corruptos sin significado. Sin embargo, aplicar fluctuaciones precisas de tensión durante la ejecución de MOVC puede forzar al MCU a emitir los bytes de código originales sin modificar, permitiendo ataques de volcado flash byte a byte ampliamente utilizados en la ingeniería inversa de canal lateral. Las instrucciones MOVX acceden a los buses de memoria externa sin cifrar, que los adversarios pueden monitorear pasivamente con analizadores lógicos para duplicar por completo el firmware sin alterar los fusibles de seguridad internos. Para el almacenamiento EEPROM interno, las variantes MOV direct permiten el acceso de lectura/escritura a los registros de funciones especiales que controlan el estado del fusible de bloqueo; las interfaces de depuración sin cerrar permiten a los atacantes aprovechar secuencias MOV simples para desbloquear el chip y realizar la extracción completa de memoria. PUSH y POP gestionan la memoria de pila, un objetivo común para las explotaciones de desbordamiento de pila que sobrescriben las direcciones de retorno y redirigen la ejecución a subrutinas maliciosas de desbloqueo. Durante la recuperación forense de hardware embebido bloqueado, los analistas rastrean todas las secuencias de instrucciones MOV para localizar puertas traseras no documentadas del fabricante dejadas intencionadamente para la reprogramación de fábrica de los dispositivos.

Instrucciones lógicas

Las instrucciones lógicas ejecutan operaciones lógicas bit a bit en las posiciones de bits correspondientes de dos operandos de byte, almacenando el resultado final calculado dentro del registro del primer operando.

Instrucciones lógicas
Mnemónico Descripción Byte Ciclo
ANL A,Rn Y bit a bit del registro de trabajo con el acumulador 1 1
ANL A,direct Y bit a bit del byte de dirección directa con el acumulador 2 2
ANL A,@Ri Y bit a bit del byte de RAM indirecto con el acumulador 1 2
ANL A,#data Y bit a bit de la constante inmediata con el acumulador 2 2
ANL direct,A Y bit a bit del acumulador con el byte de dirección directa, almacenar el resultado en el byte directo 2 3
ANL direct,#data Y bit a bit de la constante inmediata con el byte de dirección directa 3 4
ORL A,Rn O bit a bit del registro de trabajo con el acumulador 1 1
ORL A,direct O bit a bit del byte de dirección directa con el acumulador 2 2
ORL A,@Ri O bit a bit del byte de RAM indirecto con el acumulador 1 2
ORL direct,A O bit a bit del acumulador con el byte de dirección directa, almacenar el resultado en el byte directo 2 3
ORL direct,#data O bit a bit de la constante inmediata con el byte de dirección directa 3 4
XRL A,Rn XOR bit a bit del registro de trabajo con el acumulador 1 1
XRL A,direct XOR bit a bit del byte de dirección directa con el acumulador 2 2
XRL A,@Ri XOR bit a bit del byte de RAM indirecto con el acumulador 1 2
XRL A,#data XOR bit a bit de la constante inmediata con el acumulador 2 2
XRL direct,A XOR bit a bit del acumulador con el byte de dirección directa, almacenar el resultado en el byte directo 2 3
XRL direct,#data XOR bit a bit de la constante inmediata con el byte de dirección directa 3 4
CLR A Poner a cero todos los bits del registro acumulador 1 1
CPL A Invertir bit a bit todos los bits dentro del acumulador 1 1
SWAP A Intercambiar el nibble superior de 4 bits y el nibble inferior de 4 bits dentro del acumulador 1 1
RL A Rotar los bits del acumulador a la izquierda una posición (sin involucrar el acarreo) 1 1
RLC A Rotar el acumulador a la izquierda a través del bit de bandera de acarreo 1 1
RR A Rotar los bits del acumulador a la derecha una posición (sin involucrar el acarreo) 1 1
RRC A Rotar el acumulador a la derecha a través del bit de bandera de acarreo 1 1

Las instrucciones lógicas bit a bit se utilizan ampliamente para enmascarar y manipular los fusibles de bit de bloqueo y otros registros críticos de configuración de seguridad. Por ejemplo, las máscaras ANL pueden limpiar selectivamente bits individuales dentro de los SFR de control de seguridad, mientras que las máscaras ORL activan bits específicos de habilitación de fusibles. Los atacantes capaces de inyectar fallos de temporización o tensión en plena ejecución de estos códigos de operación lógicos pueden conmutar accidentalmente el estado del bit de bloqueo y desbloquear por completo el microcontrolador. Además, las instrucciones XRL de O exclusiva forman la base de las rutinas comunes de ofuscación de firmware y cifrado ligero; invertir la operación de enmascarado XOR permite a los adversarios recuperar las claves de seguridad en texto plano almacenadas en la memoria EEPROM. Para los flujos de trabajo de extracción de firmware, es obligatoria una comprensión profunda de las operaciones lógicas bit a bit para descifrar los segmentos de código protegido ofuscados antes de iniciar los volcados binarios completos de memoria.

Instrucciones orientadas a bits

Las instrucciones orientadas a bits realizan operaciones lógicas análogas al grupo lógico de ancho de byte, pero operan exclusivamente sobre ubicaciones de bits individuales en lugar de bytes completos de 8 bits.

Instrucciones orientadas a bits
Mnemónico Descripción Byte Ciclo
CLR C Limpiar el bit de estado de la bandera de acarreo a 0 lógico 1 1
CLR bit Limpiar la ubicación direccionable por bits directa especificada a 0 lógico 2 3
SETB C Activar el bit de estado de la bandera de acarreo a 1 lógico 1 1
SETB bit Activar la ubicación direccionable por bits directa especificada a 1 lógico 2 3
CPL C Invertir el estado lógico del bit de la bandera de acarreo 1 1
CPL bit Invertir el estado lógico de la ubicación de bit directa especificada 2 3
ANL C,bit Y bit a bit del bit directo objetivo con la bandera de acarreo, almacenar el resultado en C 2 2
ANL C,/bit Y bit a bit del bit objetivo invertido con la bandera de acarreo, almacenar el resultado en C 2 2
ORL C,bit O bit a bit del bit directo objetivo con la bandera de acarreo, almacenar el resultado en C 2 2
ORL C,/bit O bit a bit del bit objetivo invertido con la bandera de acarreo, almacenar el resultado en C 2 2
MOV C,bit Copiar el estado lógico del bit directo al registro de la bandera de acarreo 2 2
MOV bit,C Copiar el estado lógico de la bandera de acarreo a la ubicación de bit directa especificada 2 3

Los códigos de operación orientados a bits representan la interfaz de software principal para manipular los fusibles de bit de bloqueo y otras banderas de configuración de un solo bit críticas para la seguridad. SETB y CLR pueden alterar directamente los valores de estado de los fusibles de bloqueo, aunque la mayoría de los MCU derivados modernos del 8051 refuerzan las protecciones de hardware para que los registros de bit de bloqueo sean de solo lectura durante la ejecución normal. Los errores críticos de software que permiten el acceso de escritura a estos registros de seguridad direccionables por bits crean vectores de desbloqueo remoto para los actores malintencionados. La instrucción MOV C,bit lee el estado del fusible de bloqueo y transfiere el valor a la bandera de acarreo, que las ramas condicionales posteriores JC/JNC evalúan para hacer cumplir las restricciones de acceso a memoria. Esta secuencia estándar de comprobación de bloqueo es un objetivo principal de los ataques de inyección de fluctuaciones: invertir artificialmente la bandera de acarreo elude toda la rama de validación de seguridad. En los ataques físicos al chip basados en decapsulación, la microsonda accede directamente a estas ubicaciones de bits de fusible para leer los bits crudos del estado de bloqueo, permitiendo volcados completos y sin obstáculos de la memoria del programa sin modificar ningún código de firmware.

3.2 Descripción de todas las instrucciones del 8051

A continuación se presenta un glosario de referencia que define cada notación de operando estándar utilizada en el conjunto de instrucciones del 8051:

  • A – Registro acumulador;
  • Rn – Cualquier registro de trabajo (R0 a R7) dentro del banco de registros RAM actualmente activo;
  • Direct – Cualquier dirección RAM de byte completo de 8 bits, que abarca la RAM interna de propósito general o todos los registros de funciones especiales (puertos de E/S, registros de control, periféricos de estado);
  • @Ri – Byte de RAM interna o externa direccionado indirectamente, con la dirección de memoria contenida en el registro puntero R0 o R1;
  • #data – Constante inmediata literal de 8 bits incrustada directamente dentro del código de operación de la instrucción (rango válido 0–255);
  • #data16 – Constante inmediata literal de 16 bits almacenada como el segundo y tercer byte de una instrucción de 3 bytes (rango válido 0–65535);
  • addr16 – Dirección completa de memoria de programa de 16 bits, capaz de referenciar cualquier ubicación dentro del espacio de direcciones de código completo de 64KB;
  • addr11 – Dirección parcial de 11 bits, limitada a objetivos de salto/llamada que residen dentro de la misma página de memoria de 2KB que el byte inmediatamente posterior a la instrucción ACALL/AJMP;
  • rel – Byte de desplazamiento relativo para bifurcaciones de corto alcance, que va de -128 a +127 relativo al primer byte de la instrucción inmediatamente posterior al código de operación de bifurcación. El ensamblador calcula automáticamente el valor de desplazamiento necesario para sumar o restar de la dirección actual del contador de programa;
  • bit – Cualquier pin GPIO direccionable por bits, bandera de registro de control o bit de estado dentro del espacio RAM/SFR;
  • C – Bit global de bandera de acarreo contenido dentro del registro de palabra de estado del programa PSW.

Estas notaciones de operandos definen el espectro completo de modos de direccionamiento del 8051 y son esenciales para localizar las direcciones de los fusibles de bit de bloqueo dentro del mapa de memoria del chip. Un flujo de trabajo estándar de ingeniería inversa escanea el firmware binario en busca de referencias directas de operandos que apunten a las direcciones de memoria de los SFR de seguridad, y luego rastrea todas las rutas de instrucciones de lectura/escritura dirigidas a esos registros. Este análisis estático descubre con frecuencia modos de prueba de fábrica no documentados o rutas de código de puerta trasera ocultas que permiten la lectura completa de memoria incluso cuando la protección de bit de bloqueo permanece activa. Para los proyectos legítimos de recuperación de datos de firmware, la comprensión precisa de cada tipo de operando permite reconstruir con exactitud los diseños de volcado de memoria completos e interpretar correctamente los binarios de código extraídos.

ACALL addr11 – Llamada absoluta a subrutina de página de 2KB

addr11: Dirección de memoria de la subrutina objetivo (desplazamiento de página de 11 bits)

Descripción: Este código de operación empuja incondicionalmente la dirección de retorno del contador de programa a la pila del sistema y salta la ejecución a la dirección de subrutina especificada. Se aplica una restricción crítica: el byte siguiente de la instrucción actual y el punto de entrada de la subrutina objetivo deben residir dentro del mismo límite de página de memoria de programa de 2KB.

Sintaxis: ACALL [etiqueta_de_subrutina];
Bytes de instrucción: 2 (byte de código de operación, carga útil de dirección de 11 bits);
Banderas de estado PSW afectadas: Ninguna bandera de estado modificada por esta instrucción.

EJEMPLO:

ACALL

Valor del PC antes de la ejecución = 0123h
Valor del PC después de la ejecución = 0345h

Este código de operación de llamada a subrutina aparece con frecuencia dentro del firmware del bootloader del MCU. Los atacantes capaces de sobrescribir el operando addr11 de 11 bits mediante corrupción de memoria por desbordamiento de buffer pueden redirigir la ejecución del programa a subrutinas personalizadas de desbloqueo que deshabilitan las protecciones de bit de bloqueo. En la mayoría de los escenarios de recuperación por ingeniería inversa, el parcheo binario de la dirección objetivo de ACALL representa un método sencillo para habilitar la extracción completa del firmware flash.

ADD A,Rn – Sumar el valor del registro de trabajo al registro acumulador

A: Registro acumulador
 Rn: Cualquier registro de trabajo de R0 a R7

Descripción: El código de operación realiza una suma de bytes sin signo entre el acumulador y el registro de trabajo seleccionado Rn, almacenando la suma resultante de vuelta en el registro acumulador.

Sintaxis: ADD A,Rn;

Capítulo 3: El conjunto de instrucciones del 8051

Introducción

Escribir firmware para microcontroladores significa esencialmente enviar instrucciones ordenadas y predefinidas para realizar tareas designadas. El hardware electrónico no puede interpretar lógica descriptiva de alto nivel como "si se pulsa un pulsador, activa el LED"; en su lugar, solo reconoce un conjunto limitado de comandos estandarizados de bajo nivel decodificados por su circuitería interna. Este conjunto completo de comandos válidos se denomina CONJUNTO DE INSTRUCCIONES. Todos los microcontroladores compatibles con 8051 cuentan con un total de 255 códigos de operación de instrucciones distintos disponibles para el desarrollo de programas.

At first glance, the extensive list of mnemonic syntaxes may appear overwhelming to memorize. However, the complexity is deceptive. Many opcodes execute identical underlying operations with different addressing modes, meaning there are only 111 unique functional operations in practice. For instance, ADD A,R0, ADD A,R1 through ADD A,R7 all perform accumulator addition with a working register, and each variant counts as a separate opcode due to different register encoding. When accounting for the 53 core mathematical, logical and data transfer operations (most rarely used in practical projects), developers only need to master roughly 20 to 30 unique mnemonic abbreviations for regular programming.

Más allá de la programación funcional central, el conjunto de instrucciones está estrechamente vinculado con la arquitectura de seguridad embebida del microcontrolador. La mayoría de los chips derivados modernos del 8051 implementan fusibles de bit de bloqueo diseñados para impedir el volcado externo no autorizado del almacenamiento Flash y EEPROM en el chip. El dominio del conjunto completo de instrucciones es obligatorio tanto para implementar esquemas robustos de protección contra manipulación como para realizar ingeniería inversa legítima de firmware y recuperación de datos. Los atacantes malintencionados explotan con frecuencia comportamientos específicos de las instrucciones para eludir los mecanismos de bloqueo mediante inyección de fallos, análisis de canal lateral de temporización o ataques de sondeo físico. En numerosos escenarios reales de crackeo de hardware, la decapsulación completa del chip junto con la microsonda del troquel se utiliza para leer directamente los bits de estado de los fusibles, permitiendo la extracción binaria completa. La capacidad de replicar la lógica propietaria de un dispositivo protegido casi siempre depende del éxito del volcado de firmware a través de estos vectores de ataque, lo que convierte el análisis a nivel de instrucción en una habilidad fundamental en la investigación de seguridad de hardware embebido.

3.1 Tipos de instrucciones

Todas las instrucciones del 8051 se clasifican en cinco grupos distintos según su comportamiento funcional central:

  • Instrucciones aritméticas
  • Instrucciones de bifurcación
  • Instrucciones de transferencia de datos
  • Instrucciones lógicas
  • Instrucciones orientadas a bits

El primer segmento de cada instrucción se llama MNEMÓNICO, una abreviatura alfabética corta que representa la operación central a ejecutar (copia de datos, suma aritmética, lógica bit a bit, salto, etc.). Los mnemónicos actúan como una forma abreviada simplificada del nombre completo de la operación. A continuación se listan ejemplos representativos:

  • INC R1 – Increment general-purpose register R1 by one;
  • LJMP LAB5 – Perform a 16-bit long unconditional jump to the program label LAB5;
  • JNZ LOOP – Jump to label LOOP if the accumulator value is non-zero;

El segmento secundario de una instrucción es el OPERANDO, separado del mnemónico por al menos un carácter de espacio en blanco, que define los datos, la dirección de memoria o el registro objetivo procesados por la operación. Algunas instrucciones llevan cero operandos, mientras que otras incluyen uno, dos o tres; los múltiples operandos se separan con comas. Ejemplos de referencia:

  • RET – Return execution flow from a subroutine to the caller;
  • JZ TEMP – Jump to label TEMP when accumulator holds zero value;
  • ADD A,R3 – Sum contents of register R3 with accumulator A;
  • CJNE A,#20,LOOP – Compare immediate constant 20 against accumulator; jump to LOOP if values mismatch;

Cada clasificación de instrucciones conlleva implicaciones únicas para la seguridad del dispositivo. Los códigos de operación de manipulación de bits, por ejemplo, ofrecen acceso directo a los fusibles de bit de bloqueo y a los registros de configuración de seguridad. Las instrucciones de lectura de memoria como MOVC recuperan el código de programa crudo de la memoria Flash, devolviendo bytes inválidos alterados cuando los bits de bloqueo están habilitados. Los flujos de trabajo de ingeniería inversa priorizan la identificación de las secuencias de instrucciones que validan los estados de los fusibles de bloqueo, para luego intentar omitir estas ramas de verificación mediante fluctuaciones de reloj/tensión o manipulación del contador de programa. En casos de microcontroladores bloqueados e inutilizados, la recuperación forense a menudo se basa en localizar puertas traseras ocultas del bootloader activadas por códigos de operación de bifurcación condicional específicos para desbloquear el acceso completo de lectura de memoria.

Instrucciones aritméticas

Arithmetic instructions execute fundamental mathematical operations including addition, subtraction, multiplication and division. Upon completion of calculation, the computed result overwrites the storage of the first listed operand. Sample demonstration: ADD A,R1 stores the sum of Accumulator A and Register R1 back into A.

Instrucciones aritméticas
Mnemónico Descripción Byte Ciclo
ADD A,Rn Sumar el valor del registro Rn al acumulador A 1 1
ADD A,direct Sumar el byte de RAM/SFR direccionado directamente al acumulador A 2 2
ADD A,@Ri Sumar el byte de RAM direccionado indirectamente al acumulador A 1 2
ADD A,#data Sumar la constante inmediata de 8 bits al acumulador A 2 2
ADDC A,Rn Sumar el registro Rn más la bandera de acarreo al acumulador A 1 1
ADDC A,direct Sumar el byte directo más la bandera de acarreo al acumulador A 2 2
ADDC A,@Ri Sumar el byte de RAM indirecto más la bandera de acarreo al acumulador A 1 2
ADDC A,#data Sumar la constante inmediata más la bandera de acarreo al acumulador A 2 2
SUBB A,Rn Restar el registro Rn con bandera de préstamo del acumulador A 1 1
SUBB A,direct Restar el byte directo con bandera de préstamo del acumulador A 2 2
SUBB A,@Ri Restar el byte de RAM indirecto con bandera de préstamo del acumulador A 1 2
SUBB A,#data Restar la constante inmediata con bandera de préstamo del acumulador A 2 2
INC A Incrementar el acumulador A en uno 1 1
INC Rn Incrementar el registro de trabajo Rn en uno 1 2
INC Rx Incrementar el byte direccionado directamente en uno 2 3
INC @Ri Incrementar el byte de RAM direccionado indirectamente en uno 1 3
DEC A Decrementar el acumulador A en uno 1 1
DEC Rn Decrementar el registro de trabajo Rn en uno 1 1
DEC Rx Decrementar el byte direccionado directamente en uno 1 2
DEC @Ri Decrementar el byte de RAM direccionado indirectamente en uno 2 3
INC DPTR Incrementar el registro puntero de datos de 16 bits DPTR en uno 1 3
MUL AB Multiplicación sin signo de 8 bits del Acumulador A y el Registro B 1 5
DIV AB División sin signo de 8 bits del Acumulador A por el Registro B 1 5
DA A Corrección de ajuste decimal BCD para el acumulador A post-suma 1 1

Los códigos de operación aritméticos cumplen un doble propósito de manipulación de datos y validación de seguridad, desplegados comúnmente para calcular sumas de comprobación de integridad del firmware y rutinas ligeras de cifrado. Los atacantes pueden alterar los resultados de cálculo de la ALU mediante fluctuaciones de tensión o reloj para invalidar la lógica de comparación de sumas de comprobación, eludiendo las secuencias de autenticación de bloqueo incluso cuando los bits de fusible permanecen activos. Para los flujos de trabajo de extracción de firmware, analizar la generación de banderas de la unidad aritmética (acarreo C, desbordamiento OV, acarreo auxiliar AC) permite diseñar ataques dirigidos de inyección de fallos para omitir las subrutinas de validación de bloqueo. Las banderas de estado de acarreo y desbordamiento representan vectores de ataque principales; fluctuaciones de hardware precisas pueden forzar valores de bandera incorrectos para engañar a la lógica de salto condicional responsable de hacer cumplir las restricciones de acceso a memoria.

Instrucciones de bifurcación

Dentro de la arquitectura del 8051 existen dos categorías distintas de códigos de operación de bifurcación:

Instrucciones de salto incondicional: al ejecutarse, el flujo del programa se redirige incondicionalmente a una dirección de memoria objetivo para el procesamiento subsiguiente de instrucciones.

Instrucciones de salto condicional: la ejecución solo se bifurca a la dirección objetivo si una condición lógica predefinida se evalúa como verdadera; de lo contrario, la CPU continúa secuencialmente con la siguiente instrucción en memoria.

Instrucciones de bifurcación
Mnemónico Descripción Byte Ciclo
ACALL addr11 Llamada absoluta a subrutina de página de 2KB (dirección objetivo de 11 bits) 2 6
LCALL addr16 Llamada larga a subrutina de espacio de direcciones completo de 64KB (objetivo de 16 bits) 3 6
RET Retorno del flujo de ejecución desde una subrutina estándar 1 4
RETI Retorno del flujo de ejecución desde la rutina de servicio de interrupción 1 4
AJMP addr11 Salto incondicional absoluto de página de 2KB (dirección objetivo de 11 bits) 2 3
LJMP addr16 Salto incondicional largo de 64KB completo (dirección objetivo de 16 bits) 3 4
SJMP rel Salto relativo corto, rango de desplazamiento -128 ~ +127 bytes post-instrucción 2 3
JC rel Salto corto si la bandera de acarreo C está en nivel lógico alto (1) 2 3
JNC rel Salto corto si la bandera de acarreo C está en nivel lógico bajo (0) 2 3
JB bit,rel Salto corto si el bit de RAM/SFR direccionable especificado es igual a 1 3 4
JBC bit,rel Saltar si el bit objetivo está activado y luego limpiar automáticamente el bit objetivo 3 4
JMP @A+DPTR Salto indexado indirecto usando la dirección objetivo calculada A + DPTR 1 2
JZ rel Salto corto si el acumulador A contiene el valor cero 2 3
JNZ rel Salto corto si el acumulador A contiene un valor distinto de cero 2 3
CJNE A,direct,rel Comparar A con el byte directo; salto corto si los valores no coinciden 3 4
CJNE A,#data,rel Comparar A con la constante inmediata; salto corto si los valores no coinciden 3 4
CJNE Rn,#data,rel Comparar el registro de trabajo Rn con la constante inmediata; salto si no coinciden 3 4
CJNE @Ri,#data,rel Comparar el byte de RAM indirecto con la constante inmediata; salto si no coinciden 3 4
DJNZ Rn,rel Decrementar el registro Rn, salto corto si el resultado es distinto de cero 2 3
DJNZ Rx,rel Decrementar el byte directo, salto corto si el resultado es distinto de cero 3 4
NOP Sin operación; consumir un ciclo de máquina sin cambios de estado 1 1

Las instrucciones de bifurcación condicional forman la lógica central de todas las subrutinas de validación de seguridad. El código de operación JB, por ejemplo, se implementa universalmente para sondear los bits de estado de los fusibles de bloqueo. Si el bit de fusible está activado en estado bloqueado, la CPU se bifurca a una subrutina que deshabilita las interfaces de depuración y bloquea las operaciones externas de lectura de memoria. Los atacantes de hardware explotan las fluctuaciones de reloj/tensión para corromper la lógica de muestreo de lectura de bits de JB, forzando al MCU a tratar un bit de bloqueo activado como desactivado y eludir la protección por completo. De manera similar, los códigos de operación de comparación CJNE alimentan los bucles de verificación de contraseñas y claves criptográficas; la inyección precisa de fallos en plena comparación manipula los resultados de bifurcación para redirigir la ejecución a rutinas de lectura de firmware desprotegidas. En el análisis de ingeniería inversa, mapear el grafo completo de bifurcaciones del programa es un paso obligatorio para localizar puntos de entrada de desbloqueo ocultos y parchear las imágenes binarias para la recuperación de datos de dispositivos bloqueados.

Instrucciones de transferencia de datos

Los códigos de operación de transferencia de datos copian el contenido de registros y memoria entre ubicaciones de almacenamiento, dejando los datos de origen sin modificar tras la operación. Las variantes con el sufijo "X" (MOVX) facilitan el intercambio bidireccional de datos con el espacio de memoria de datos externa.

Instrucciones de transferencia de datos
Mnemónico Descripción Byte Ciclo
MOV A,Rn Copiar el valor del registro de trabajo Rn al acumulador A 1 1
MOV A,direct Copiar el valor del byte direccionado directamente al acumulador A 2 2
MOV A,@Ri Copiar el valor del byte de RAM direccionado indirectamente al acumulador A 1 2
MOV A,#data Cargar el valor constante inmediato de 8 bits directamente en el acumulador A 2 2
MOV Rn,A Copiar el valor del acumulador A al registro de trabajo Rn 1 2
MOV Rn,direct Copiar el valor del byte directo al registro de trabajo Rn 2 4
MOV Rn,#data Cargar la constante inmediata de 8 bits en el registro de trabajo Rn 2 2
MOV direct,A Copiar el valor del acumulador A al byte de memoria/SFR direccionado directamente 2 3
MOV direct,Rn Copiar el valor del registro de trabajo Rn a la dirección de byte directo 2 3
MOV direct,direct Copiar datos entre dos direcciones de byte directo separadas 3 4
MOV direct,@Ri Copiar el valor del byte de RAM indirecto a la dirección de byte directo 2 4
MOV direct,#data Cargar la constante inmediata de 8 bits en la dirección de byte directo 3 3
MOV @Ri,A Copiar el valor del acumulador A a la ubicación de RAM direccionada indirectamente 1 3
MOV @Ri,direct Copiar el valor del byte directo a la ubicación de RAM direccionada indirectamente 2 5
MOV @Ri,#data Cargar la constante inmediata de 8 bits en la dirección de RAM indirecta 2 3
MOV DPTR,#data Cargar la constante inmediata de 16 bits en el puntero de datos de 16 bits DPTR 3 3
MOVC A,@A+DPTR Leer el byte de memoria Flash de código indexado por A + DPTR en el acumulador A 1 3
MOVC A,@A+PC Leer el byte de memoria Flash de código indexado por A + contador de programa PC en A 1 3
MOVX A,@Ri Leer la RAM de datos externa de dirección de 8 bits en el acumulador A 1 3-10
MOVX A,@DPTR Leer la RAM de datos externa de dirección de 16 bits en el acumulador A 1 3-10
MOVX @Ri,A Escribir el valor del acumulador A en la RAM de datos externa de dirección de 8 bits 1 4-11
MOVX @DPTR,A Escribir el valor del acumulador A en la RAM de datos externa de dirección de 16 bits 1 4-11
PUSH direct Empujar el valor del byte directo a la pila de la CPU, incrementar el puntero de pila SP 2 4
POP direct Extraer el valor superior de la pila al byte directo, decrementar el puntero de pila SP 2 3
XCH A,Rn Intercambiar el contenido completo de 8 bits del acumulador A y el registro Rn 1 2
XCH A,direct Intercambiar el contenido completo de 8 bits de A y el byte direccionado directamente 2 3
XCH A,@Ri Intercambiar el contenido completo de 8 bits de A y el byte de RAM indirecto 1 3
XCHD A,@Ri Intercambiar solo el nibble inferior de 4 bits entre A y el byte de RAM indirecto 1 3

Los códigos de operación de transferencia de datos constituyen las instrucciones más frecuentemente ejecutadas en todo el firmware embebido, y a la vez actúan como superficies de ataque principales para la explotación de hardware. Las variantes MOVC están diseñadas específicamente para acceder al espacio de memoria Flash del programa; cuando los fusibles de bit de bloqueo están programados como activos, estas instrucciones devuelven bytes corruptos sin significado para bloquear el volcado de código. Sin embargo, las fluctuaciones precisas de tensión de alimentación durante la ejecución de MOVC pueden interrumpir la lógica de protección de lectura de memoria, permitiendo a los atacantes extraer el binario Flash crudo byte a byte, una técnica convencional de ingeniería inversa de canal lateral. Los códigos de operación MOVX apuntan a los buses de memoria de datos externa, que permanecen sin cifrar y son fácilmente monitoreables mediante analizadores lógicos para duplicar el firmware completo sin ataques físicos a nivel de troquel. Para el almacenamiento EEPROM en el chip que contiene números de serie, datos de calibración y claves criptográficas, las instrucciones directas de lectura/escritura MOV acceden a los registros SFR de control de seguridad, incluidos los bits de configuración de bloqueo. Las interfaces de depuración sobrantes accidentalmente en el firmware de producción permiten a los adversarios usar secuencias MOV simples para desactivar los bloqueos del chip y realizar volcados completos de memoria. Los códigos de operación de manipulación de pila PUSH y POP introducen vectores de vulnerabilidad de desbordamiento de pila; las cargas maliciosas pueden sobrescribir las direcciones de retorno de la pila para redirigir la ejecución de la CPU a subrutinas personalizadas que deshabilitan la protección de bloqueo. Durante la recuperación forense de MCU bloqueados, los analistas rastrean todas las secuencias de instrucciones MOV para localizar puertas traseras no documentadas del fabricante diseñadas para la extracción autorizada completa de memoria.

Instrucciones lógicas

Las instrucciones lógicas realizan operaciones matemáticas bit a bit sobre los bits individuales correspondientes de dos operandos de 8 bits, almacenando el resultado final calculado dentro de la ubicación de almacenamiento del primer operando al completarse.

Instrucciones lógicas
Mnemónico Descripción Byte Ciclo
ANL A,Rn Y bit a bit entre el acumulador A y el registro de trabajo Rn 1 1
ANL A,direct Y bit a bit entre el acumulador A y el byte de memoria/SFR directo 2 2
ANL A,@Ri Y bit a bit entre el acumulador A y el byte de RAM direccionado indirectamente 1 2
ANL A,#data Y bit a bit entre el acumulador A y la constante inmediata de 8 bits 2 2
ANL direct,A Y bit a bit entre el byte directo y el acumulador A, almacenar el resultado en el byte directo 2 3
ANL direct,#data Y bit a bit entre el byte directo y la constante inmediata, almacenar el resultado en el byte directo 3 4
ORL A,Rn O bit a bit entre el acumulador A y el registro de trabajo Rn 1 1
ORL A,direct O bit a bit entre el acumulador A y el byte de memoria/SFR directo 2 2
ORL A,@Ri O bit a bit entre el acumulador A y el byte de RAM direccionado indirectamente 1 2
ORL direct,A O bit a bit entre el byte directo y el acumulador A, almacenar el resultado en el byte directo 2 3
ORL direct,#data O bit a bit entre el byte directo y la constante inmediata, almacenar el resultado en el byte directo 3 4
XRL A,Rn XOR bit a bit entre el acumulador A y el registro de trabajo Rn 1 1
XRL A,direct XOR bit a bit entre el acumulador A y el byte de memoria/SFR directo 2 2
XRL A,@Ri XOR bit a bit entre el acumulador A y el byte de RAM direccionado indirectamente 1 2
XRL A,#data XOR bit a bit entre el acumulador A y la constante inmediata de 8 bits 2 2
XRL direct,A XOR bit a bit entre el byte directo y el acumulador A, almacenar el resultado en el byte directo 2 3
XORL direct,#data XOR bit a bit entre el byte directo y la constante inmediata, almacenar el resultado en el byte directo 3 4
CLR A Poner los 8 bits del acumulador A a 0 lógico 1 1
CPL A Invertir bit a bit cada bit dentro del acumulador A (0 ↔ 1) 1 1
SWAP A Intercambiar el nibble alto superior de 4 bits y el nibble bajo inferior de 4 bits del acumulador A 1 1
RL A Rotar los 8 bits del acumulador A a la izquierda una posición, el bit7 se envuelve al bit0 1 1
RLC A Rotar el acumulador A a la izquierda a través de la bandera de acarreo C, el bit7 se desplaza a C, C se desplaza al bit0 1 1
RR A Rotar los 8 bits del acumulador A a la derecha una posición, el bit0 se envuelve al bit7 1 1
RRC A Rotar el acumulador A a la derecha a través de la bandera de acarreo C, el bit0 se desplaza a C, C se desplaza al bit7 1 1

Los códigos de operación lógicos bit a bit son herramientas principales para enmascarar y modificar los registros de fusibles de bit de bloqueo y los SFR de configuración de seguridad. El mnemónico ANL limpia selectivamente bits de registro individuales, mientras que ORL activa selectivamente los bits objetivo dentro de la memoria de configuración. La inyección de fallos de hardware en plena ejecución de estas instrucciones puede corromper los valores de los operandos para conmutar involuntariamente los estados de los fusibles de bloqueo y desbloquear por completo el microcontrolador. La instrucción XRL de O exclusiva se implementa ampliamente dentro de las rutinas de ofuscación de firmware y cifrado ligero; invertir la operación de enmascarado XOR permite a los atacantes recuperar las claves de seguridad en texto plano almacenadas dentro de la EEPROM en el chip. Para los flujos de trabajo completos de volcado de firmware, es obligatorio el dominio completo de la aritmética bit a bit para descifrar los segmentos de código protegidos antes de la extracción y desensamblado binario.

Instrucciones orientadas a bits

Los códigos de operación orientados a bits comparten similitudes funcionales con las instrucciones lógicas generales, pero operan exclusivamente sobre bits de memoria individuales independientes direccionables por bits en lugar de bytes completos de 8 bits.

Instrucciones orientadas a bits
Mnemónico Descripción Byte Ciclo
CLR C Forzar la bandera de acarreo C al valor lógico bajo 0 1 1
CLR bit Limpiar el bit de RAM/SFR direccionable especificado a 0 lógico 2 3
SETB C Forzar la bandera de acarreo C al valor lógico alto 1 1 1
SETB bit Activar el bit de RAM/SFR direccionable especificado a 1 lógico 2 3
CPL C Invertir el estado lógico actual de la bandera de acarreo C (0 ↔ 1) 1 1
CPL bit Invertir el estado lógico del bit objetivo direccionable individual (0 ↔ 1) 2 3
ANL C,bit Operación Y bit a bit entre la bandera de acarreo C y el bit de RAM especificado 2 2
ANL C,/bit Y bit a bit entre la bandera de acarreo C y el estado invertido del bit de RAM objetivo 2 2
ORL C,bit Operación O bit a bit entre la bandera de acarreo C y el bit de RAM especificado 2 2
ORL C,/bit O bit a bit entre la bandera de acarreo C y el estado invertido del bit de RAM objetivo 2 2
MOV C,bit Copiar el estado lógico del bit objetivo direccionable en la bandera de acarreo C 2 2
MOV bit,C Copiar el estado lógico actual de la bandera de acarreo C en el bit objetivo direccionable 2 3

Los códigos de operación de manipulación de bits constituyen el mecanismo principal para modificar directamente los fusibles de bit de bloqueo y otros bits de estado críticos para la seguridad. Los comandos SETB y CLR pueden alterar directamente los estados de los fusibles de bloqueo, aunque los MCU derivados convencionales del 8051 refuerzan los bits de bloqueo como de solo lectura durante la ejecución estándar para bloquear el desbloqueo por software. Los errores críticos de firmware ocasionalmente exponen el acceso de escritura a los registros de control de bloqueo, permitiendo el desbloqueo remoto por software a través de estos códigos de operación de bits. La instrucción MOV C,bit recupera el estado del fusible de bloqueo en el registro de la bandera de acarreo, que los saltos condicionales posteriores JC/JNC evalúan para hacer cumplir las restricciones de acceso a memoria. Esta secuencia de leer-luego-bifurcar representa un objetivo principal para los ataques de fluctuación de hardware; invertir el valor lógico de la bandera de acarreo en plena ejecución elude por completo la lógica de autenticación de bloqueo. En los flujos de trabajo de ingeniería inversa por decapsulación física, estas celdas de almacenamiento de bits individuales se sondean directamente bajo un microscopio para leer los estados crudos de los fusibles de bloqueo, eliminando la necesidad de cualquier exploit de software para volcar la memoria completa del código del dispositivo.

3.2 Descripción de todas las instrucciones del 8051

A continuación se presenta un glosario estandarizado que define cada notación de operando utilizada en toda la sintaxis de instrucciones del 8051:

  • A – Registro acumulador, registro de trabajo principal de 8 bits de aritmética/lógica;
    Rn – Cualquiera de los ocho registros de trabajo de propósito general en bancos R0 a R7 dentro del banco de registros RAM activo;
  • Direct – Cualquier dirección de memoria completa de 8 bits que va de 00h a FFh; puede referenciar ubicaciones de RAM interna de propósito general o Registros de Funciones Especiales (SFR), incluidos puertos de E/S y registros de control;
  • @Ri – Puntero de direccionamiento indirecto de memoria que utiliza el registro R0 o R1 para contener la dirección del byte de RAM objetivo;
  • #data – Constante inmediata literal de 8 bits incrustada directamente dentro del flujo de bytes del código de operación de la instrucción, rango de valores 00h a FFh;
  • #data16 – Constante inmediata literal de 16 bits almacenada como el segundo y tercer byte de una instrucción de 3 bytes, rango 0000h a FFFFh;
  • addr16 – Dirección objetivo completa de memoria de programa de 16 bits, válida para cualquier ubicación dentro del espacio de direcciones de código Flash completo de 64KB;
  • addr11 – Dirección de memoria de programa truncada de 11 bits; la dirección objetivo debe residir dentro de la misma página de memoria de 2KB que el byte inmediatamente posterior a la instrucción ACALL/AJMP;
  • rel – Valor de desplazamiento relativo con signo de 8 bits para instrucciones de salto corto, rango de desplazamiento -128 a +127 bytes relativo al primer byte de la instrucción inmediatamente posterior al código de operación de bifurcación; el ensamblador calcula automáticamente este valor de desplazamiento a partir de las direcciones de etiquetas definidas por el usuario;
  • bit – Cualquier pin direccionable por bits, bandera de registro de control o bit de almacenamiento RAM;
  • C – Bit de estado de la bandera de acarreo almacenado dentro del registro SFR de la Palabra de Estado del Programa (PSW).

Estas notaciones de operandos estandarizadas definen todos los modos de direccionamiento válidos del 8051 y sirven como puntos de referencia críticos para localizar las direcciones de los fusibles de bit de bloqueo dentro del mapa de memoria del chip. Un flujo de trabajo estándar de ingeniería inversa escanea todos los códigos de operación de direccionamiento directo que referencian los desplazamientos de memoria de los SFR de control de seguridad, y luego rastrea cada instrucción de lectura/escritura dirigida a esas direcciones para descubrir interfaces de prueba ocultas del fabricante o puertas traseras no documentadas que permiten volcados completos de memoria sin protección. Para la extracción forense de firmware, la comprensión precisa de cada clasificación de operandos es obligatoria para reconstruir volcados de memoria completos precisos e interpretar correctamente el código binario desensamblado recuperado de microcontroladores bloqueados.

ACALL addr11 - Llamada absoluta a subrutina

addr11: Dirección de memoria de subrutina objetivo de 11 bits

Descripción: Este código de operación desencadena un salto incondicional para ejecutar una subrutina separada ubicada en la dirección de memoria de programa de 11 bits especificada. Una restricción firme exige que la dirección actual del contador de programa y la dirección de la subrutina objetivo existan dentro del mismo bloque contiguo de 2KB de memoria Flash, medido a partir del primer byte de la instrucción que sigue a ACALL.

Sintaxis: ACALL [etiqueta de subrutina];
Bytes: 2 (byte de código de operación primario, dirección de subrutina truncada de 11 bits);
Banderas del registro STATUS: Ninguna bandera de estado PSW se modifica o afecta durante la ejecución.

EJEMPLO:

MOV Rx,@Ri

Dirección del registro SUM=F3
Antes de la ejecución: SUM=58h R1=F3
Después de la ejecución: SUM=58h TEMP=58h

MOV direct1,direct2 - Mueve el byte directo al byte directo

```html

Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)
 Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)

Descripción: Esta instrucción copia datos de un byte direccionable directamente a otro byte direccionable directamente. Dado que se utiliza el direccionamiento directo, tanto el operando de origen como el de destino pueden ser cualquier Registro de Función Especial (SFR) o registro RAM de propósito general ubicado dentro del rango de direcciones 0x00–0x7F (0–127 decimal). El operando de origen direct1 conserva su valor original después de la ejecución.

Sintaxis: MOV direct1,direct2;
Recuento de bytes: 3 (byte de código de operación, byte de dirección direct1, byte de dirección direct2);
Banderas del registro STATUS: Ninguna bandera de estado se modifica.

EJEMPLO:

MOV Rx,Ry

Estado previo a la ejecución: TEMP=0x58
Estado posterior a la ejecución: TEMP=0x58 SUM=0x58

MOV @Ri,A – Copiar los datos del acumulador a la RAM interna direccionada indirectamente

A: Registro acumulador
 Ri: Registro de direccionamiento indirecto, ya sea R0 o R1

Descripción: La instrucción transfiere el valor almacenado en el acumulador a la ubicación de RAM interna cuya dirección está contenida en Ri (R0 o R1). El valor del acumulador permanece sin cambios al completarse la ejecución.

Sintaxis: MOV @Ri,A;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

MOV @Ri,A

Dirección de RAM objetivo SUM=0xF2h
Estado previo a la ejecución: R0=0xF2h A=0x58h
Estado posterior a la ejecución: SUM=0x58h A=0x58h

MOV direct,#data – Cargar el valor constante inmediato en un byte direccionable directamente

Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)
 Datos: Valor constante de 8 bits entre 0 y 255 (0x00 a 0xFF)

Descripción: Esta instrucción escribe un valor constante inmediato en una ubicación de byte direccionable directamente. El direccionamiento directo permite que el byte objetivo sea cualquier SFR o registro RAM de propósito general dentro del espacio de direcciones 0x00–0x7F (0–127 decimal).

Sintaxis: MOV direct,#data;
Recuento de bytes: 3 (byte de código de operación, byte de dirección directa objetivo, byte de datos inmediato);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

MOV Rx,#X

Estado posterior a la ejecución: TEMP=0x22h

MOV @Ri,#data – Cargar la constante inmediata en la RAM interna direccionada indirectamente

Ri: Registro de direccionamiento indirecto R0 o R1
 Datos: Valor constante de 8 bits entre 0 y 255 (0x00 a 0xFF)

Descripción: La instrucción almacena un valor constante inmediato en la dirección de RAM interna apuntada por Ri (R0 o R1).

Sintaxis: MOV @Ri,#data;
Recuento de bytes: 2 (byte de código de operación, byte de datos inmediato);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

MOV @Ri,#X

Dirección de RAM objetivo TEMP=0xE2h
Estado previo a la ejecución: R1=0xE2h
Estado posterior a la ejecución: TEMP=0x44h

MOV @Ri,direct – Copiar los datos del byte directo a la RAM interna direccionada indirectamente

Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)
 Ri: Registro de direccionamiento indirecto R0 o R1

Descripción: Esta instrucción copia el valor de un byte direccionable directamente en la ubicación de RAM interna cuya dirección está almacenada dentro de Ri (R0 o R1). El byte directo de origen conserva su valor original después de completarse la operación.

Sintaxis: MOV @Ri,direct;
Recuento de bytes: 2 (byte de código de operación, byte de dirección directa de origen);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

MOV @Ri,Rx

Dirección de RAM objetivo TEMP=0xE2h
Estado previo a la ejecución: SUM=0x58h R1=0xE2h
Estado posterior a la ejecución: SUM=0x58h TEMP=0x58h

MOV bit,C – Copiar el estado de la bandera de acarreo a una dirección de bit directa

C: Bit de la bandera de acarreo dentro del registro PSW
 Bit: Cualquier bit direccionable individualmente de la RAM interna

Descripción: La instrucción transfiere el estado lógico de la bandera de acarreo a una ubicación de RAM direccionable por bits especificada. El valor de la bandera de acarreo permanece sin cambios después de la ejecución.

Sintaxis: MOV bit,C;
Recuento de bytes: 2 (byte de código de operación, byte de dirección del bit objetivo);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

MOV bit,C

Regla posterior a la ejecución: si C=0 entonces P1.2=0
Si C=1 entonces P1.2=1

MOV C,bit – Copiar el estado del bit directo en la bandera de acarreo

C: Bit de la bandera de acarreo dentro del registro PSW
 Bit: Cualquier bit direccionable individualmente de la RAM interna

Descripción: Esta instrucción carga el valor lógico de una ubicación de RAM direccionable por bits especificada en la bandera de acarreo. El estado del bit de origen se conserva después de que finaliza la ejecución.

Sintaxis: MOV C,bit;
Recuento de bytes: 2 (byte de código de operación, byte de dirección del bit de origen);
Banderas del registro STATUS: La bandera de acarreo (C) se actualiza;

EJEMPLO:

MOV C,bit

Regla posterior a la ejecución: si P1.4=0 entonces C=0
Si P1.4=1 entonces C=1

Esta instrucción lee el bit del fusible de bloqueo en la bandera de acarreo. Una fluctuación de tensión o reloj que invierta el bit objetivo durante la operación de lectura corromperá el valor de la bandera de acarreo, lo que puede permitir a los atacantes eludir la lógica de validación de bloqueo.

MOVC A,@A+DPTR – Leer el byte de memoria de programa desplazado por el acumulador desde DPTR al acumulador

A: Registro acumulador
 DPTR: Par de registros puntero de datos de 16 bits (DPH + DPL)

Descripción: La instrucción primero calcula la suma del valor del registro DPTR de 16 bits y el valor del acumulador de 8 bits. La dirección de 16 bits resultante apunta a un byte dentro de la memoria flash del programa, que luego se carga en el registro acumulador.

Sintaxis: MOVC A,@A+DPTR;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

MOVC A,@A+DPTR

Estados previos a la ejecución:
DPTR=0x1000:
A=0
A=1
A=2
A=3

Estados posteriores a la ejecución:
A=0x66
A=0x77
A=0x88
A=0x99

Nota: DB (Define Byte) es una directiva del ensamblador utilizada para definir valores constantes de byte estáticos dentro de la memoria del programa.

Este es el código de operación principal utilizado para leer el contenido de la memoria flash del programa. Los microcontroladores bloqueados devolverán datos basura revueltos cuando esta instrucción se ejecute normalmente, pero los atacantes pueden inyectar fluctuaciones en el bus de direcciones para forzar la salida correcta de bytes sin revolver, permitiendo el volcado completo byte a byte del firmware flash.

MOV DPTR,#data16 – Cargar la constante inmediata de 16 bits en el registro puntero de datos

Datos: Valor constante de 16 bits que va de 0 a 65535 (0x0000 a 0xFFFF)
 DPTR: Registro puntero de datos de 16 bits compuesto por DPH (byte alto) y DPL (byte bajo)

Descripción: Esta instrucción almacena una constante inmediata de 16 bits en el par de registros DPTR. Los 8 bits superiores de la constante pueblan el registro DPH, mientras que los 8 bits inferiores pueblan el registro DPL.

Sintaxis: MOV DPTR,#data;
Recuento de bytes: 3 (byte de código de operación, byte alto de la constante bits 15–8, byte bajo de la constante bits 7–0);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

MOV DPTR,#X16

Estado posterior a la ejecución: DPH=0x12 DPL=0x34

MOVX A,@Ri – Leer los datos de RAM externa de dirección de 8 bits al acumulador

Ri: Registro de direccionamiento indirecto R0 o R1
 A: Registro acumulador

Descripción: El código de operación lee los datos almacenados en una dirección de 8 bits dentro de la RAM externa y los copia en el registro acumulador. La dirección de RAM externa objetivo está contenida en Ri (R0 o R1).

Sintaxis: MOVX A,@Ri;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

MOVX A,@Ri

Dirección de RAM externa: SUM=0x12h
Estado previo a la ejecución: SUM=0x58h R0=0x12h
Estado posterior a la ejecución: A=0x58h

Nota:
La ubicación de almacenamiento SUM reside dentro del espacio de direcciones bajas de RAM externa de 256 bytes.

La memoria RAM externa normalmente no está cifrada y es susceptible al rastreo de señales de bus, lo que permite a los adversarios capturar datos confidenciales sensibles sin desbloquear los bloqueos de seguridad del microcontrolador.

MOVC A,@A+PC – Leer el byte de memoria de programa desplazado por el acumulador desde el contador de programa al acumulador

A: Registro acumulador
 PC: Registro contador de programa de 16 bits

Descripción: La instrucción calcula la suma del valor actual del contador de programa de 16 bits y el valor del acumulador de 8 bits. La dirección resultante apunta a un byte dentro de la memoria flash del programa, que se carga en el registro acumulador.

Sintaxis: MOVC A,@A+PC;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

MOVC A,@A+PC

Después de ejecutar la subrutina etiquetada "Table", uno de los cuatro valores constantes distintos se almacenará en el registro acumulador:

Valores del acumulador previos a la ejecución:
A=0
A=1
A=2
A=3

Valores del acumulador posteriores a la ejecución:
A=0x66
A=0x77
A=0x88
A=0x99

Nota: DB (Define Byte) es una directiva del ensamblador utilizada para definir valores constantes de byte estáticos dentro de la memoria del programa.

Esta instrucción secundaria de lectura de memoria de programa comparte vectores de explotación con la variante MOVC basada en DPTR. Si las fluctuaciones de reloj o tensión pueden eludir los fusibles de bloqueo de seguridad, los atacantes pueden aprovechar este código de operación para volcar por completo la imagen completa del firmware flash.

MOVX @Ri,A – Escribir los datos del acumulador en la RAM externa de dirección de 8 bits

Ri: Registro de direccionamiento indirecto R0 o R1
 A: Registro acumulador

Descripción: Esta instrucción copia el valor almacenado en el acumulador a una ubicación de RAM externa cuya dirección de 8 bits está almacenada dentro de Ri (R0 o R1).

Sintaxis: MOVX @Ri,A;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

MOVX @Ri,A

Dirección de RAM externa: SUM=0x34h
Estado previo a la ejecución: A=0x58 R1=0x34h
Estado posterior a la ejecución: SUM=0x58h

NOTA:
La ubicación de almacenamiento SUM se encuentra dentro del espacio de direcciones bajas de RAM externa de 256 bytes.

MOVX A,@DPTR – Leer los datos de RAM externa de dirección de 16 bits al acumulador

A: Registro acumulador
 DPTR: Par de registros puntero de datos de 16 bits (DPH + DPL)

Descripción: El código de operación carga el valor de byte almacenado en la dirección de RAM externa de 16 bits contenida en DPTR (DPH contiene el byte de dirección alto, DPL el byte de dirección bajo) en el registro acumulador.

Sintaxis: MOVX A,@DPTR;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

MOVX A,@DPTR

Dirección de RAM externa: SUM=0x1234h
Estado previo a la ejecución: DPTR=0x1234h SUM=0x58
Estado posterior a la ejecución: A=0x58h

Nota:
La ubicación de almacenamiento SUM reside dentro del espacio de direcciones completo de 64KB de la RAM externa.

MUL AB – Multiplicación sin signo de 8 bits del acumulador y el registro B

A: Registro acumulador
 B: Registro B de propósito general

Descripción: Esta instrucción multiplica el valor sin signo de 8 bits del acumulador por el valor sin signo de 8 bits almacenado en el registro B. Los 8 bits inferiores del producto de 16 bits resultante se guardan dentro del acumulador, mientras que los 8 bits superiores se almacenan dentro del registro B. Si el valor del producto supera los 255 decimales, se activa la bandera de desbordamiento (OV); la bandera de acarreo (C) permanece sin afectar.

Sintaxis: MUL AB;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

MUL AB

Estado previo a la ejecución: A=80 (0x50) B=160 (0xA0)
Estado posterior a la ejecución: A=0x00 B=0x32
Producto matemático: A·B = 80 × 160 = 12800 (0x3200)

MOVX @DPTR,A – Escribir los datos del acumulador en la RAM externa de dirección de 16 bits

A: Registro acumulador
 DPTR: Par de registros puntero de datos de 16 bits (DPH + DPL)

Descripción: Esta instrucción copia el valor de byte del acumulador en la ubicación de RAM externa direccionada por la dirección completa de 16 bits almacenada dentro de DPTR (DPH = byte de dirección alto, DPL = byte de dirección bajo).

Sintaxis: MOVX @DPTR,A;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

MOVX @DPTR,A

Dirección de RAM externa: SUM=0x1234h
Estado previo a la ejecución: A=0x58 DPTR=0x1234h
Estado posterior a la ejecución: SUM=0x58h

Nota:
La ubicación de almacenamiento SUM reside dentro del espacio de direcciones completo de 64KB de la RAM externa.

ORL A,Rn – O lógico bit a bit entre el acumulador y el registro de trabajo Rn

Rn: Cualquier registro de trabajo de R0 a R7
 A: Registro acumulador

Descripción: La instrucción realiza una operación O lógica bit a bit entre el valor del acumulador y el valor almacenado en el registro de trabajo objetivo Rn. La salida bit a bit resultante se escribe de vuelta en el registro acumulador.

Sintaxis: ORL A,Rn;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

ORL A,Rn

Estado previo a la ejecución: A=0xC3 (Binario 11000011)
R5=0x55 (Binario 01010101)
Estado posterior a la ejecución: A=0xD7 (Binario 11010111)

NOP – Ciclo sin operación

Descripción: Este código de operación no ejecuta ninguna manipulación de datos ni operaciones lógicas, y se utiliza exclusivamente para introducir retardos de temporización fijos precisos en el flujo de ejecución del código.

Sintaxis: NOP;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

NOP

La secuencia de ensamblador proporcionada genera un pulso lógico negativo con una duración exacta de 5 ciclos de máquina en el pin P2.3. Al utilizar un oscilador de cristal de 12 MHz, cada ciclo de máquina consume 1 microsegundo, creando un pulso descendente de 5 microsegundos en este pin de salida.

ORL A,@Ri – O lógico bit a bit entre el acumulador y el byte de RAM interna direccionado indirectamente

Ri: Registro de direccionamiento indirecto R0 o R1
 A: Registro acumulador

Descripción: La instrucción ejecuta una operación O lógica bit a bit entre el valor del acumulador y el byte almacenado en la dirección de RAM interna apuntada por Ri (direccionamiento indirecto R0/R1). El resultado bit a bit resultante sobrescribe el valor del registro acumulador.

Sintaxis: ANL A,@Ri;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

ANL A,@Ri

Dirección de RAM indirecta objetivo: TEMP=0xFAh
Estado previo a la ejecución: R1=0xFAh
TEMP=0xC2 (Binario 11000010)
A=0x54 (Binario 01010100)
Estado posterior a la ejecución: A=0xD6 (Binario 11010110)

ORL A,direct – O lógico bit a bit entre el acumulador y el byte direccionable directamente

Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)
 A: Registro acumulador

Descripción: Este código de operación calcula un O lógico bit a bit entre el acumulador y una ubicación de byte direccionable directamente. El direccionamiento directo permite que el byte objetivo sea cualquier SFR o registro RAM de propósito general dentro del rango de direcciones 0x00–0x7F (0–127 decimal). El resultado de salida bit a bit se almacena de vuelta en el registro acumulador.

Sintaxis: ORL A,direct;
Recuento de bytes: 2 (byte de código de operación, byte de dirección directa objetivo);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

ORL A,Rx

Estado previo a la ejecución: A=0xC2 (Binario 11000010)
LOG=0x54 (Binario 01010100)
Estado posterior a la ejecución: A=0xD6 (Binario 11010110)

ORL direct,A – O lógico bit a bit entre el byte direccionable directamente y el acumulador, almacenar el resultado en el byte directo

Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)
 A: Registro acumulador

Descripción: La instrucción realiza una operación O lógica bit a bit entre una ubicación de byte direccionable directamente y el registro acumulador. El direccionamiento directo admite todos los SFR y registros RAM de propósito general dentro del rango de direcciones 0x00–0x7F (0–127 decimal). El resultado bit a bit calculado sobrescribe el valor original del byte directo.

Sintaxis: ORL [dirección de registro], A;
Recuento de bytes: 2 (byte de código de operación, dirección de byte directo);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

ORL Rx,A

Estado previo a la ejecución: TEMP=0xC2 (Binario 11000010)
A=0x54 (Binario 01010100)
Estado posterior a la ejecución: A=0xD6 (Binario 11010110)

ORL A,#data – O lógico bit a bit entre el acumulador y la constante inmediata de 8 bits

Datos: Valor constante de 8 bits entre 0 y 255 (0x00 a 0xFF)
 A: Registro acumulador

Descripción: Este código de operación ejecuta una operación O lógica bit a bit entre el registro acumulador y un byte constante inmediato en línea. El valor bit a bit resultante se guarda en el registro acumulador.

Sintaxis: ORL A, #data;
Recuento de bytes: 2 (byte de código de operación, byte de constante inmediata);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

ORL A, #X

Estado previo a la ejecución: A=0xC2 (Binario 11000010)
Estado posterior a la ejecución: A=0xC3 (Binario 11000011)

ORL C,bit – O lógico bit a bit entre el bit directo y la bandera de acarreo, actualizar la bandera de acarreo

C: Bit de la bandera de acarreo dentro del registro PSW
 Bit: Cualquier bit direccionable individualmente de la RAM interna

Descripción: La instrucción calcula un O lógico bit a bit entre el estado lógico de una ubicación de RAM direccionable por bits especificada y el valor actual de la bandera de acarreo, luego escribe el estado de un bit resultante de vuelta en el registro de la bandera de acarreo.

Sintaxis: ORL C,bit;
Recuento de bytes: 2 (byte de código de operación, byte de dirección del bit objetivo);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

ORL C,bit

Estado previo a la ejecución: ACC=0xC6 (Binario 11001010)
C=0
Estado posterior a la ejecución: C=1

ORL direct,#data – O lógico bit a bit entre el byte direccionable directamente y la constante inmediata, almacenar el resultado en el byte directo

Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)
 Datos: Valor constante de 8 bits entre 0 y 255 (0x00 a 0xFF)

Descripción: Este código de operación realiza una operación O lógica bit a bit entre un byte constante inmediato y un byte de memoria direccionable directamente. El direccionamiento directo admite todos los SFR y registros RAM de propósito general dentro del rango de direcciones 0x00–0x7F (0–127 decimal). La salida bit a bit calculada sobrescribe el valor original del byte directo.

Sintaxis: ORL [dirección de registro],#data;
Recuento de bytes: 3 (byte de código de operación, dirección de byte directo, byte de datos inmediato);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

ORL Rx,#X

Estado previo a la ejecución: TEMP=0xC2 (Binario 11000010)
Estado posterior a la ejecución: A=0xD2 (Binario 11010010)

POP direct – Recuperar el byte de la pila y almacenarlo en el registro direccionable directamente

Direct: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)

Descripción: La instrucción primero lee los datos de byte almacenados en la dirección de memoria apuntada por el registro puntero de pila. Este valor de byte se copia en el registro direccionable directamente especificado, después de lo cual el valor del registro puntero de pila se decrementa en uno. El direccionamiento directo permite que el registro objetivo sea cualquier SFR o registro RAM de propósito general dentro del rango de direcciones 0x00–0x7F (0–127 decimal).

Sintaxis: POP direct;
Recuento de bytes: 2 (byte de código de operación, dirección de byte directo);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

POP Rx

Mapa de direcciones de memoria previo a la ejecución: Dirección Valor
0x30 0x20
0x31 0x23
SP ==> 0x32 0x01
DPTR=0x0123 (DPH=0x01, DPL=0x23)

Mapa de direcciones de memoria posterior a la ejecución: Dirección Valor
SP ==> 0x30 0x20
0x31 0x23
0x32 0x01

ORL C,/bit – O lógico bit a bit entre el bit directo invertido y la bandera de acarreo, actualizar la bandera de acarreo

C: Bit de la bandera de acarreo dentro del registro PSW
 Bit: Cualquier bit direccionable individualmente de la RAM interna

Descripción: Este código de operación ejecuta una operación O lógica bit a bit entre la inversa lógica de la ubicación de RAM direccionable por bits objetivo y el valor actual de la bandera de acarreo, luego escribe el estado de un bit resultante de vuelta en el registro de la bandera de acarreo.

valor crudo del bit /bit (bit invertido) valor inicial de C C = C O /bit Resultado
0 1 0 0
0 1 1 1
1 0 0 0
1 0 1 0

Sintaxis: ORL C,/bit;
Recuento de bytes: 2 (byte de código de operación, byte de dirección del bit);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

ORL C,/bit

Estado previo a la ejecución: ACC=0xC6 (Binario 11001010)
C=0
Estado posterior a la ejecución: C=0

RET – Instrucción de retorno de subrutina

Descripción: Este código de operación termina la ejecución de cada bloque de subrutina de ensamblador. Después de finalizar RET, la ejecución del programa se reanuda en la instrucción inmediatamente posterior al código de operación previo de llamada a subrutina ACALL o LCALL.

Sintaxis: RET;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

RET

PUSH direct – Almacenar el byte direccionable directamente en la pila del programa

Datos: Registro de propósito general con dirección que va de 0 a 255 (0x00 a 0xFF)

Descripción: El valor del registro puntero de pila se incrementa primero en uno, luego el valor de byte del registro direccionable directamente especificado se copia en la ubicación de memoria de pila apuntada por el puntero de pila actualizado. El direccionamiento directo admite todos los SFR y registros RAM de propósito general dentro del rango de direcciones 0x00–0x7F (0–127 decimal).

Sintaxis: PUSH direct;
Recuento de bytes: 2 (byte de código de operación, dirección de byte directo);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

PUSH Rx

Mapa de direcciones de memoria previo a la ejecución: Dirección Valor
SP ==> 0x30 0x20
DPTR=0x0123 (DPH=0x01, DPL=0x23)

Mapa de direcciones de memoria posterior a la ejecución: Dirección Valor
0x30 0x20
0x31 0x23
SP ==> 0x32 0x01

RL A – Rotar los bits del acumulador a la izquierda una posición (bandera de acarreo excluida)

A: Registro acumulador

Descripción: Los ocho bits contenidos dentro del registro acumulador se rotan a la izquierda en una sola posición de bit. El bit más significativo (bit 7) del acumulador se envuelve y se convierte en el nuevo bit menos significativo (bit 0).

Sintaxis: RL A;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

RL A

Estado previo a la ejecución: A=0xC2 (Binario 11000010)
Estado posterior a la ejecución: A=0x85 (Binario 10000101)

RL A

RETI – Instrucción de retorno de rutina de servicio de interrupción

Descripción: Este código de operación termina cada subrutina de servicio de interrupción y señala al núcleo del microcontrolador que el manejo de la interrupción ha finalizado. Después de la ejecución, el flujo del programa se reanuda desde la ubicación de instrucción exacta interrumpida por el evento de hardware. El estado del registro de la Palabra de Estado del Programa (PSW) no se restaura automáticamente a su valor previo a la interrupción por el hardware.

Sintaxis: RETI;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

RR A – Rotar los bits del acumulador a la derecha una posición (bandera de acarreo excluida)

A: Registro acumulador

Descripción: Los ocho bits dentro del registro acumulador se rotan a la derecha en una sola posición de bit. El bit menos significativo (bit 0) se envuelve y se convierte en el nuevo bit más significativo (bit 7).

Sintaxis: RR A;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

RR A

Estado previo a la ejecución: A=0xC2 (Binario 11000010)
Estado posterior a la ejecución: A=0x61 (Binario 01100001)

Rotación a la derecha

RLC A – Rotar el acumulador a la izquierda un bit a través de la bandera de acarreo

A: Registro acumulador

Descripción: Los ocho bits del acumulador y el bit único de la bandera de acarreo forman un registro de desplazamiento colectivo de 9 bits rotado a la izquierda una posición. El MSB del acumulador (bit7) se mueve a la bandera de acarreo, y el bit original de la bandera de acarreo se desplaza al LSB del acumulador (bit0).

Sintaxis: RLC A;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: La bandera de acarreo (C) se actualiza;

EJEMPLO:

RLC A

Estado previo a la ejecución: A=0xC2 (Binario 11000010)
C=0
Estado posterior a la ejecución: A=0x85 (Binario 10000100)
C=1

Rotación a la izquierda a través del bit de acarreo

SETB C – Forzar el estado lógico de la bandera de acarreo a 1

C: Bit de la bandera de acarreo dentro del registro PSW

Descripción: Este código de operación activa el bit de la bandera de acarreo a un estado lógico alto permanente (1).

Sintaxis: SETB C;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: La bandera de acarreo (C) se activa a 1;

EJEMPLO:

SETB C

Estado posterior a la ejecución: C=1

La modificación de la bandera de acarreo (SETB C / CLR C) se utiliza comúnmente para controlar las instrucciones de salto condicional (JC / JNC). En los escenarios de ingeniería inversa y ataque de hardware, los adversarios pueden inyectar fluctuaciones de tensión o reloj para invertir la bandera de acarreo en plena ejecución de las bifurcaciones condicionales, forzando al microcontrolador a ejecutar una ruta de código no intencionada que frecuentemente elude la lógica de validación del bloqueo de seguridad. Esta técnica clásica de inyección de fallos permite el desbloqueo del dispositivo sin requerir la decapsulación completa del chip para el sondeo físico.

RRC A – Rotar el acumulador a la derecha un bit a través de la bandera de acarreo

A: Registro acumulador

Descripción: Los ocho bits del acumulador más la bandera de acarreo forman un registro de desplazamiento de 9 bits rotado a la derecha una posición. El LSB del acumulador (bit0) se transfiere a la bandera de acarreo, mientras que el bit original de la bandera de acarreo se desplaza al MSB del acumulador (bit7).

Sintaxis: RRC A;
Recuento de bytes: 1 (un solo byte de código de operación);
Banderas del registro STATUS: La bandera de acarreo (C) se actualiza;

EJEMPLO:

RRC A

Estado previo a la ejecución: A=0xC2 (Binario 11000010)
C=0
Estado posterior a la ejecución: A=0x61 (Binario 01100001)
C=0

Rotación a la derecha a través del bit de acarreo

SJMP rel – Salto incondicional relativo corto

addr: Dirección objetivo del salto por desplazamiento relativo

Descripción: Este código de operación realiza un salto incondicional a una dirección de memoria objetivo dentro de un rango de desplazamiento relativo de -128 a +128 bytes medido desde la dirección de la instrucción inmediatamente posterior al código de operación SJMP.

Sintaxis: SJMP [dirección de salto];
Recuento de bytes: 2 (byte de código de operación, byte de desplazamiento relativo con signo);
Banderas del registro STATUS: Ninguna bandera de estado se modifica;

EJEMPLO:

SJMP rel

Valor del contador de programa previo a la ejecución: PC=323
Valor del contador de programa posterior a la ejecución: PC=345

SETB bit – Activar el bit de RAM direccionable por bits especificado a 1 lógico

Bit: Cualquier bit direccionable individualmente de la RAM interna

Descripción: El código de operación fuerza el bit de memoria direccionable por bits seleccionado a lógico alto (1). El registro padre que contiene este bit debe pertenecer al subconjunto de SFR y registros RAM direccionables por bits definidos en la especificación de la arquitectura del 8051.

Sintaxis: SETB [dirección de bit];
Recuento de bytes: 2 (byte de código de operación, byte de dirección del bit objetivo);
Banderas del registro STATUS: Ninguna bandera de estado se altera;

EJEMPLO:

SETB bit

Antes de la ejecución: P0.1 = 34h (00110100)
El pin 1 está configurado como salida
Después de la ejecución: P0.1 = 35h (00110101)
El pin 1 está configurado como entrada

La instrucción de bit SETB sirve como la operación inversa de la instrucción de bit CLR. Si bien se adopta ampliamente para la configuración general de pines, también introduce vulnerabilidades de seguridad potenciales si los atacantes pueden aprovecharla para alterar los estados de los bits de bloqueo. No obstante, la mayoría de los microcontroladores basados en 8051 implementan restricciones de hardware que bloquean al software la modificación de los bits de bloqueo, limitando los riesgos de esta instrucción a registros de bits no críticos para la seguridad. En escenarios donde el firmware contiene errores sin parchear, los actores malintencionados pueden explotar SETB para activar modos de prueba de fábrica no documentados, que otorgan acceso completo de lectura a la memoria flash del programa en el chip.

SUBB A,direct – Restar el byte de dirección directa del Acumulador con entrada de préstamo

Direct: Cualquier registro de propósito general o de función especial con un rango de direcciones de 0 a 255 (00h a FFh)
 A: Registro acumulador

Descripción: Esta instrucción realiza una operación de resta entre el Acumulador y un byte de memoria de dirección directa, incorporando la bandera de préstamo de acarreo en el cálculo. Se afirmará una bandera de acarreo (C) si un bit de orden superior debe pedir prestado de un bit de orden inferior durante la resta. Como operación de direccionamiento directo, el byte objetivo puede referenciar cualquier SFR o registro RAM de propósito general dentro del espacio de direcciones 0–7Fh (0–127 decimal). El resultado aritmético final se almacena dentro del registro Acumulador.

Sintaxis: SUBB A,direct;
Recuento de bytes de la instrucción: 2 (byte de código de operación + byte de dirección directa);
Banderas del registro STATUS afectadas: C, OV, AC;

EJEMPLO:

SUBB A,Rx

Antes de la ejecución: A=C9h, DIF=53h, C=0
Después de la ejecución: A=76h, C=0

SUBB A,Rn – Restar el valor del registro de trabajo Rn del Acumulador con entrada de préstamo

Rn: Cualquier registro de trabajo de R0 a R7
 A: Registro acumulador

Descripción: Esta instrucción resta el valor de 8 bits almacenado en el registro de trabajo Rn seleccionado del Acumulador, teniendo en cuenta la bandera de préstamo de acarreo existente. La bandera de acarreo C se activará cuando se requiera un préstamo a través de los límites de bits durante la resta. El valor de 8 bits resultante se escribe de vuelta al registro Acumulador.

Sintaxis: SUBB A,Rn;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: C, OV, AC;

EJEMPLO:

SUBB A,Rn

Antes de la ejecución: A=C9h, R4=54h, C=1
Después de la ejecución: A=74h, C=0

Nota:
El resultado matemático difiere del cálculo crudo C9 − 54 = 75 porque la bandera de acarreo C se afirma (C=1) antes de la ejecución de la instrucción, lo que deduce un valor de préstamo adicional del total de la resta.

SUBB A,#data – Restar una constante inmediata de 8 bits del Acumulador con entrada de préstamo

A: Registro acumulador
 Datos: Constante estática de 8 bits que va de 0 a 255 (00h a FFh)

Descripción: Esta instrucción resta un valor de byte inmediato codificado en duro del Acumulador, incluyendo la bandera de préstamo de acarreo en la operación aritmética. La bandera de acarreo C se eleva siempre que ocurra un préstamo a nivel de bits durante la resta. El resultado calculado se almacena dentro del registro Acumulador.

Sintaxis: SUBB A,#data;
Recuento de bytes de la instrucción: 2 (byte de código de operación + byte de datos inmediato);
Banderas del registro STATUS afectadas: C, OV, AC;

EJEMPLO:

SUBB A,#X

Antes de la ejecución: A=C9h, C=0
Después de la ejecución: A=A7h, C=0

SUBB A,@Ri – Restar los datos de RAM interna direccionados indirectamente del Acumulador con entrada de préstamo

Ri: Registro puntero de direccionamiento indirecto, ya sea R0 o R1
 A: Registro acumulador

Descripción: Esta instrucción recupera un valor de 8 bits de la RAM interna usando direccionamiento indirecto a través de Ri, luego resta este valor del Acumulador teniendo en cuenta la bandera de préstamo de acarreo. Si se necesita un préstamo entre bits durante la resta, se activará la bandera de acarreo C. La dirección de RAM objetivo está contenida dentro del registro puntero Ri (R0 o R1). El resultado final de la resta se guarda en el registro Acumulador.

Sintaxis: SUBB A,@Ri;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: C, OV, AC;

EJEMPLO:

SUBB A,@Ri

Etiqueta de dirección de RAM objetivo: MIN=F4h
Antes de la ejecución: A=C9h, R1=F4h, MIN=04h, C=0
Después de la ejecución: A=C5h, C=0

XCH A,Rn – Intercambiar los contenidos de datos entre el Acumulador y un registro de trabajo Rn

Rn: Cualquier registro de trabajo R0 a R7
 A: Registro acumulador

Descripción: Esta instrucción realiza una operación de intercambio de byte completo entre el Acumulador y el registro de trabajo Rn especificado. El valor de 8 bits almacenado en el Acumulador se copia a Rn, y simultáneamente el valor original de Rn se carga en el registro Acumulador.

Sintaxis: XCH A,Rn;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XCH A,Rn

Antes de la ejecución: A=C6h, R3=29h
Después de la ejecución: R3=C6h, A=29h

SWAP A – Intercambiar los nibbles alto y bajo de 4 bits dentro del registro Acumulador

A: Registro acumulador

Descripción: Un nibble se refiere a un segmento de 4 bits de un byte de 8 bits, dividido en nibble bajo (bits 0–3) y nibble alto (bits 4–7). Esta instrucción intercambia las posiciones de los nibbles de orden alto y bajo por completo dentro del registro Acumulador.

Sintaxis: SWAP A;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

SWAP A

Antes de la ejecución: A=E1h (binario 11100001).
Después de la ejecución: A=1Eh (binario 00011110).

Intercambiar nibbles dentro del acumulador

XCH A,@Ri – Intercambiar datos de byte entre el Acumulador y la RAM interna direccionada indirectamente

Ri: Registro puntero indirecto R0 o R1
 A: Registro acumulador

Descripción: Esta instrucción intercambia el contenido completo de byte del Acumulador con una ubicación de RAM interna objetivo mediante direccionamiento indirecto. La dirección de RAM a acceder está almacenada dentro del registro puntero Ri (ya sea R0 o R1).

Sintaxis: XCH A,@Ri;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XCH A,@Ri

Etiqueta de dirección de RAM objetivo: SUM=E3h
Antes de la ejecución: R0=E3h, SUM=29h, A=98h
Después de la ejecución: A=29h, SUM=98h

XCH A,direct – Intercambiar datos de byte entre el Acumulador y un byte de registro de dirección directa

Direct: Cualquier registro/SFR con rango de direcciones de 0 a 255 (00h a FFh)
 A: Registro acumulador

Descripción: Esta instrucción intercambia el valor completo de 8 bits contenido en el Acumulador con el valor almacenado en una ubicación de memoria de dirección directa. El direccionamiento directo admite el acceso a cualquier SFR o registro RAM de propósito general dentro del rango de direcciones 0–7Fh (0–127 decimal).

Sintaxis: XCH A,direct;
Recuento de bytes de la instrucción: 2 (byte de código de operación + byte de dirección directa);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XCH A,Rx

Antes de la ejecución: A=FFh, SUM=29h
Después de la ejecución: SUM=FFh, A=29h

XRL A,Rn – Realizar la operación XOR bit a bit entre el Acumulador y el registro de trabajo Rn

Rn: Cualquier registro de trabajo R0 a R7
 A: Registro acumulador

Descripción: Esta instrucción ejecuta una operación lógica O-exclusiva bit a bit entre el Acumulador y el registro Rn seleccionado. El valor XOR de 8 bits resultante se sobrescribe en el registro Acumulador.

Sintaxis: XRL A,Rn;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XRL A,Rn

Antes de la ejecución: A= C3h (Binario 11000011)
R3= 55h (Binario 01010101)
Después de la ejecución: A= 96h (Binario 10010110)

XCHD A,@Ri – Intercambiar solo los nibbles inferiores de 4 bits entre el Acumulador y la RAM direccionada indirectamente

Ri: Registro puntero indirecto R0 o R1
 A: Registro acumulador

Descripción: Esta instrucción intercambia únicamente los nibbles de orden inferior (bits 0–3) del Acumulador y el byte de RAM interna direccionado indirectamente. Los nibbles de orden superior de 4 bits tanto del Acumulador como de la ubicación de RAM objetivo permanecen sin cambios. Esta operación se utiliza principalmente para el procesamiento aritmético BCD. La dirección de RAM objetivo está almacenada dentro del registro puntero Ri (R0 o R1).

Sintaxis: XCHD A,@Ri;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XCHD A,@Ri

Etiqueta de dirección de RAM objetivo: SUM=E3h
Antes de la ejecución: R0=E3h SUM=29h A=A8h,
Después de la ejecución: A=A9h, SUM=28h

Intercambiar el contenido de los nibbles bajos del acumulador con el registro direccionado indirectamente Rx

XRL A,@Ri – Realizar XOR bit a bit entre el Acumulador y los datos de RAM interna direccionados indirectamente

Ri: Registro puntero indirecto R0 o R1
 A: Registro acumulador

Descripción: Esta instrucción calcula un O-exclusiva bit a bit entre el Acumulador y el valor almacenado en una ubicación de RAM interna direccionada indirectamente. La dirección de RAM está contenida en el registro puntero Ri (R0 o R1). El resultado XOR final se escribe de vuelta al registro Acumulador.

Sintaxis: XRL A,@Ri;
Recuento de bytes de la instrucción: 1 (un solo byte de código de operación);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XRL A,@Ri

Etiqueta de dirección de RAM objetivo: TEMP=FAh, R1=FAh
Antes de la ejecución: TEMP= C2h (Binario 11000010)
A= 54h (Binario 01010100)
Después de la ejecución: A= 96h (Binario 10010110)

XRL A,direct – Ejecutar XOR bit a bit entre el Acumulador y el byte de registro de dirección directa

Direct: Cualquier registro/SFR con rango de direcciones de 0 a 255 (00h a FFh)
 A: Registro acumulador

Descripción: Esta instrucción ejecuta un cálculo de O-exclusiva bit a bit utilizando el Acumulador y un byte de memoria de dirección directa. El direccionamiento directo permite el acceso a cualquier SFR o registro RAM de propósito general dentro del rango de direcciones 0–7Fh (0–127 decimal). El resultado XOR calculado se almacena en el registro Acumulador.

Sintaxis: XRL A,direct;
Recuento de bytes de la instrucción: 2 (byte de código de operación + byte de dirección directa);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XRL A,Rx

Antes de la ejecución: A= C2h (Binario 11000010)
LOG= 54h (Binario 01010100)
Después de la ejecución: A= 96h (Binario 10010110)

XRL direct,A – Ejecutar XOR bit a bit entre el byte de registro de dirección directa y el Acumulador

Direct: Cualquier registro/SFR con rango de direcciones de 0 a 255 (00h a FFh)
 A: Registro acumulador

Descripción: Esta instrucción realiza una operación de O-exclusiva bit a bit combinando un byte de memoria de dirección directa y el valor del Acumulador. El direccionamiento directo admite todos los SFR y registros RAM de propósito general en el espacio de direcciones 0–7Fh. El valor XOR resultante se guarda en el registro objetivo de dirección directa en lugar del Acumulador.

Sintaxis: XRL direct,A;
Recuento de bytes de la instrucción: 2 (byte de código de operación + byte de dirección directa);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XRL Rx,A

Antes de la ejecución: TEMP= C2h (Binario 11000010)
A= 54h (Binario 01010100)
Después de la ejecución: TEMP= 96h (Binario 10010110)

XRL A,#data – Realizar XOR bit a bit entre el Acumulador y una constante inmediata de 8 bits

Datos: Constante estática de 8 bits de 0 a 255 (00h a FFh)
 A: Registro acumulador

Descripción: Esta instrucción calcula un O-exclusiva bit a bit entre el Acumulador y un valor de byte inmediato codificado en duro. La salida de la lógica XOR se almacena dentro del registro Acumulador.

Sintaxis: XRL A,#data;
Recuento de bytes de la instrucción: 2 (byte de código de operación + byte de datos inmediato);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XRL A,#X

Antes de la ejecución: A= C2h (Binario 11000010)
X= 11h (Binario 00010001)
Después de la ejecución: A= D3h (Binario 11010011)

XRL direct,#data – Ejecutar XOR bit a bit entre el byte de registro de dirección directa y la constante inmediata

Direct: Cualquier registro/SFR con rango de direcciones de 0 a 255 (00h a FFh)
 Datos: Constante estática de 8 bits de 0 a 255 (00h a FFh)

Descripción: Esta instrucción calcula un O-exclusiva bit a bit entre un valor constante inmediato y un byte de memoria de dirección directa. El direccionamiento directo otorga acceso a todos los SFR y registros RAM de propósito general dentro del rango de direcciones 0–7Fh. El resultado XOR se escribe en la ubicación del registro objetivo de dirección directa.

Sintaxis: XRL direct,#data;
Recuento de bytes de la instrucción: 3 (byte de código de operación + byte de dirección directa + byte de datos inmediato);
Banderas del registro STATUS afectadas: Ninguna bandera modificada;

EJEMPLO:

XRL Rx,#X

Antes de la ejecución: TEMP= C2h (Binario 11000010)
X=12h (Binario 00010010)
Después de la ejecución: TEMP= D0h (Binario 11010000)

 

Capítulo 4 : Microcontrolador AT89S8253

Introducción

Han transcurrido más de dos décadas desde el lanzamiento original del núcleo fundamental del microcontrolador 8051. A lo largo de este período, la arquitectura ha experimentado extensas mejoras iterativas y ampliaciones funcionales. Hoy en día, decenas de fabricantes de semiconductores en todo el mundo producen variantes derivadas compatibles de microcontroladores comercializadas bajo números de pieza de producto distintos. Las iteraciones modernas actualizadas ofrecen conjuntos de características enormemente ampliados en comparación con el diseño base original del 8051. La mayoría de estos derivados llevan etiquetas como "compatible con 8051", "conforme a 8051" o "familia 8051" para resaltar su linaje arquitectónico compartido. Estas etiquetas significan arquitecturas de CPU central idénticas y modelos de programación uniformes que utilizan el conjunto de instrucciones estándar del 8051. En los flujos de trabajo prácticos de desarrollo, el dominio de un solo dispositivo dentro de esta familia permite la migración sin fricciones a cualquier otro modelo compatible, otorgando a los ingenieros acceso a cientos de SKU de microcontroladores distintos.

Este capítulo se centra en el microcontrolador AT89S8253 fabricado por Atmel como miembro representativo de la familia. Este dispositivo específico fue seleccionado para un análisis detallado debido a su adopción industrial generalizada, su bajo costo unitario y su memoria de programa Flash integrada. La característica de almacenamiento Flash lo hace ideal para prototipado y pruebas iterativas, ya que las imágenes de programa pueden borrarse y reprogramarse repetidamente miles de veces. Además, su interfaz de programación serie SPI integrada permite la reprogramación de firmware incluso después de que el chip haya sido soldado permanentemente en las placas de circuito de los productos finales.

Sin embargo, esta conveniente programabilidad en circuito introduce riesgos críticos de exposición de la seguridad del firmware. Si los bits de bloqueo de hardware del dispositivo permanecen sin programar, el contenido completo de la memoria Flash del programa puede leerse externamente a través de la interfaz de programación SPI. Atmel integró un mecanismo de bloqueo de memoria de programa de hardware de tres niveles para bloquear la extracción externa no autorizada de firmware. No obstante, los fusibles de seguridad de hardware no son invulnerables a la elusión, independientemente del fabricante del microcontrolador. Los ingenieros inversos malintencionados han desplegado con éxito ataques de decapsulación de chip y microsonda para eludir las protecciones de los bits de bloqueo y recuperar imágenes binarias completas de firmware. En ciertos escenarios de explotación, la partición EEPROM en el chip – que almacena parámetros de calibración confidenciales, identificadores de serie y claves criptográficas – puede volcarse por completo utilizando la instrucción MOVX cuando el bit de control EEMEN está habilitado. Esta vulnerabilidad inherente subraya la necesidad de que los desarrolladores embebidos comprendan completamente los mecanismos de seguridad nativos del AT89S8253 al diseñar productos que requieren garantías sólidas de confidencialidad e integridad del firmware.

El AT89S8253 también integra un módulo de temporizador watchdog de hardware que puede configurarse para detectar eventos de manipulación y desencadenar un reinicio inmediato del sistema completo. La configuración adecuada del watchdog sirve como contramedida anti-extracción: si un atacante intenta detener la ejecución de la CPU para realizar sondas de bus o volcados de memoria, el tiempo de espera del watchdog forzará un reinicio del dispositivo e interrumpirá los intentos de recuperación de datos. Aun así, los adversarios pueden explotar ataques de fluctuación de reloj o la manipulación directa de los registros SFR de control del watchdog para deshabilitar el temporizador, siempre que esos registros permanezcan desprotegidos por las restricciones de los bits de bloqueo. El despliegue combinado de los fusibles de bit de bloqueo y la lógica de reinicio del watchdog establece una barrera de seguridad de hardware multicapa que aumenta la complejidad y el costo de la clonación de dispositivos y la ingeniería inversa. Como se observa en todos los microcontroladores de la familia 8051, ningún primitivo de seguridad de hardware ofrece protección absoluta. La recuperación completa del firmware típicamente requiere combinar múltiples metodologías de ataque, incluido el análisis de canal lateral electromagnético, las fluctuaciones de inyección de fallos de tensión, y la decapsulación completa del silicio para exponer los fusibles de seguridad internos y las celdas de memoria. Tanto las defensas de seguridad embebidas como las técnicas de extracción maliciosas continúan evolucionando junto con el despliegue industrial convencional de microcontroladores.

4.1 Las especificaciones de identificación del microcontrolador AT89S8253

  • Completamente compatible con el conjunto de instrucciones de la arquitectura clásica del núcleo 8051.
  • 12 Kilobytes de memoria de programa Flash programable en el sistema.
    • Las imágenes binarias de firmware se cargan a través de la Interfaz Periférica Serie SPI integrada.
    • La memoria Flash admite hasta 1,000 ciclos combinados de borrado y escritura de programa.
  • 2 Kilobytes de almacenamiento de datos EEPROM no volátil en el chip.
  • Rango de tensión de alimentación de operación: 4V a 6V CC.
  • Frecuencia de reloj del oscilador externo admitida: 0 MHz hasta 24 MHz.
  • 256 bytes de RAM interna volátil para el almacenamiento de variables en tiempo de ejecución.
  • 32 pines de entrada/salida digital de propósito general distribuidos en cuatro puertos de 8 bits.
  • Tres módulos periféricos independientes de temporizador/contador de 16 bits.
  • Nueve fuentes distintas de entrada de interrupción de hardware.
  • Dos modos operativos suplementarios de bajo consumo: modo Idle y modo Power-Down.
  • Periférico de comunicación serie asíncrona UART de hardware configurable.
  • Periférico de temporizador watchdog programable integrado.
  • Sistema de protección de fusibles de bloqueo de memoria de programa de hardware de tres niveles.
Resumen del microcontrolador AT89S8253

El troquel semiconductor del AT89S8253 se empaqueta en tres factores de forma industriales estándar:

Encapsulado DIP Encapsulado TQFP Encapsulado PLCC

El factor de forma del empaque físico afecta directamente la dificultad de los ataques destructivos de decapsulación. Los empaques más grandes con una superficie de silicio expuesta aumentada (como DIP y PLCC) son significativamente más fáciles de disecar y sondear con microsonda para los adversarios que los empaques compactos de montaje superficial TQFP. Independientemente de la variante de empaque, los bits de bloqueo de hardware permanecen como la primera línea de defensa contra el volcado externo de firmware a través de la interfaz de programación. Las mejores prácticas de la industria exigen programar el nivel de bloqueo de seguridad más alto disponible para deshabilitar todos los comandos de lectura SPI. Muchos equipos de diseño de hardware refuerzan aún más los dispositivos deshabilitando permanentemente la circuitería del pin de programación SPI después de la producción en masa para elevar la barrera contra los intentos no autorizados de extracción de firmware.

4.2 Descripciones funcionales del pinout

VCC Entrada principal de alimentación positiva (rango de operación CC de 4V a 6V)

GND Referencia de tierra eléctrica del sistema (rieles de alimentación negativa)

Puerto 0 (P0.0–P0.7) Cuando se configuran como salidas digitales, cada pin puede impulsar hasta 8 cargas de entrada lógica TTL estándar. Cuando se configuran en modo entrada, los pines del Puerto 0 operan como entradas flotantes de alta impedancia con niveles de tensión indefinidos relativos a la tierra del sistema. Cuando se implementa la expansión de memoria de datos o de programa externa, el Puerto 0 sirve como bus multiplexado de direcciones/datos. La señal del pin de control ALE dicta si los valores de dirección o de datos se transmiten a través de las líneas del bus del Puerto 0.

Puerto 1 (P1.0–P1.7) En configuración de salida, cada pin del Puerto 1 puede impulsar hasta 4 cargas de entrada TTL. Cuando se configuran como entradas, estos pines actúan como entradas estándar compatibles con TTL con resistencias de pull-up internas débiles conectadas al riel de alimentación de 5V de VCC. Cada pin del Puerto 1 también presenta funciones periféricas alternativas secundarias dedicadas, listadas en la tabla siguiente:

Identificador de pin del puerto Función periférica alternativa
P1.0 T2 (entrada de contador externo del Temporizador 2)
P1.1 T2EX (entrada de control de disparo externo del Temporizador 2)
P1.4 SS (señal de control de selección de esclavo del periférico SPI)
P1.5 MOSI (línea de datos de salida de maestro / entrada de esclavo SPI)
P1.6 MISO (línea de datos de entrada de maestro / salida de esclavo SPI)
P1.7 SCK (señal de reloj serie síncrono SPI)

Puerto 2 (P2.0–P2.7) Las características eléctricas del Puerto 2 coinciden con las del Puerto 1 tanto para los modos operativos de entrada como de salida. Cuando se utiliza la expansión de memoria externa, el Puerto 2 emite el byte alto de 8 bits del bus de direcciones de memoria de 16 bits (A8–A15) para el direccionamiento de memoria objetivo.

Puerto 3 (P3.0–P3.7) El Puerto 3 comparte una funcionalidad idéntica de entrada/salida de propósito general con el Puerto 1, y cada pin implementa funciones periféricas alternativas secundarias dedicadas detalladas más adelante dentro de este capítulo.

Identificador de pin del puerto Función periférica alternativa
P3.0 RXD (entrada de datos de recepción serie UART)
P3.1 TXD (salida de datos de transmisión serie UART)
P3.2 INT0 (entrada de disparo de interrupción de hardware externa 0)
P3.3 INT1 (entrada de disparo de interrupción de hardware externa 1)
P3.4 T0 (entrada de contador de eventos externos del Temporizador 0)
P3.5 T1 (entrada de contador de eventos externos del Temporizador 1)
P3.6 WR (señal de control de escritura de memoria de datos externa)
P3.7 RD (señal de control de lectura de memoria de datos externa)

RST Un nivel de tensión lógico alto (1 digital) aplicado a este pin desencadena una secuencia completa de reinicio de hardware del microcontrolador.

ALE/PROG Durante la operación estándar en tiempo de ejecución, el pin ALE genera una señal de pulso de reloj continua a una frecuencia igual a 1/16 de la frecuencia del oscilador principal, utilizable para circuitos externos de temporización y generación de reloj. Cuando la expansión de memoria externa está activa, la señal ALE fija el byte de dirección bajo de 8 bits (A0–A7) transmitido sobre el Puerto 0. Durante las operaciones de programación en el sistema Flash, este pin también actúa como una línea de entrada de control de programación dedicada.

PSEN Este pin emite una señal de estroboscopio activa-baja utilizada exclusivamente para acceder a dispositivos de memoria ROM de programa externos fuera del chip.

EA/VPP Conectar este pin directamente a la tierra del sistema fuerza a la CPU a buscar todas las instrucciones de programa de la memoria de programa externa fuera del chip. Para las aplicaciones embebidas estándar que utilizan la memoria Flash de programa en el chip (el escenario de despliegue más común), este pin debe conectarse al riel de alimentación positivo VCC. Durante los ciclos de programación Flash de alta tensión, este pin recibe una tensión de polarización de programación de +12V.

XTAL 1 Pin de entrada del circuito del oscilador interno. Este terminal se interconecta con componentes de oscilador de cristal externos o fuentes externas de señal de reloj de precisión para la operación síncrona de la CPU.

XTAL 2 Pin de salida del circuito del oscilador interno. Este pin permanece sin usar cuando se suministra una señal de reloj externa independiente a XTAL1.

4.3 La arquitectura de memoria del microcontrolador AT89S8253

Memoria de programa (Flash ROM)

El banco de memoria de programa de 12 Kilobytes se implementa utilizando tecnología de semiconductores Flash de compuerta flotante, permitiendo ciclos repetidos de borrado y reprogramación de firmware. Todas las imágenes binarias de programa se escriben en la Flash a través de la interfaz periférica serie SPI integrada en la placa. La expansión de memoria ROM de programa externa fuera del chip se admite como una extensión de hardware opcional, aunque la capacidad Flash nativa de 12KB satisface la mayoría de los requisitos de aplicaciones embebidas sin hardware de memoria externa adicional.

Desde la perspectiva de la amenaza a la seguridad de hardware, la memoria Flash de programa en el chip representa el objetivo principal para los ataques no autorizados de recuperación de firmware. Los fusibles de bit de bloqueo programados adecuadamente bloquean todos los comandos externos de lectura devueltos a través de la interfaz de programación SPI. Sin embargo, el acceso físico al chip empaquetado permite ataques de decapsulación costosos pero comprobados que despojan el empaque protector de epoxi para exponer el troquel de silicio, permitiendo la microsonda eléctrica directa de las celdas de almacenamiento Flash individuales. Para mitigar este vector de ataque físico de alto costo, Atmel implementó tres niveles jerárquicos de bloqueo de seguridad, aunque todos los esquemas de protección basados en fusibles de hardware permanecen susceptibles al equipo y las técnicas avanzadas de laboratorio de ingeniería inversa.

Memoria de acceso aleatorio (RAM)

El espacio de RAM volátil interno se particiona en tres bloques discretos de memoria de 128 bytes, adhiriéndose estrictamente a la especificación de diseño de memoria estándar original del 8051:

  • 128 bytes de RAM de trabajo de propósito general en tiempo de ejecución;
  • 128 ubicaciones de direcciones reservadas asignadas exclusivamente para los Registros de Funciones Especiales (SFR). Las direcciones SFR sin poblar y sin usar no pueden reutilizarse para el almacenamiento general de variables; y
  • Un banco adicional de 128 bytes de RAM auxiliar de propósito general sin funciones de periféricos de hardware dedicados. Estas ubicaciones de memoria comparten desplazamientos de direcciones idénticos con el bloque SFR y solo son accesibles mediante modos de instrucción de direccionamiento indirecto.
Memoria RAM

Memoria de datos no volátil EEPROM

La EEPROM es un medio de almacenamiento no volátil híbrido que combina la flexibilidad de lectura/escritura aleatoria de la RAM con la característica de retención de datos persistente de la ROM. Los datos escritos en la EEPROM permanecen almacenados indefinidamente sin alimentación continua al microcontrolador. El AT89S8253 integra un total de 2 Kilobytes (2048 ubicaciones de bytes individuales) de almacenamiento EEPROM dedicado en el chip.

Esta partición EEPROM se utiliza convencionalmente para almacenar números de serie únicos del dispositivo, coeficientes de calibración de fábrica y claves de seguridad criptográficas confidenciales. La lectura no autorizada exitosa de la partición EEPROM expone todos los datos secretos embebidos sensibles almacenados dentro. Si bien los bits de bloqueo de hardware también restringen las operaciones de lectura EEPROM basadas en SPI externas, este banco de almacenamiento permanece vulnerable al análisis de fuga de canal lateral electromagnético y a los ataques de fluctuación de inyección de fallos de tensión. En escenarios de explotación específicos, los volcados completos de memoria EEPROM pueden ejecutarse utilizando la secuencia de instrucciones de memoria externa MOVX cuando el bit de control EEMEN dentro del SFR EECON está afirmado, creando una vulnerabilidad de puerta trasera de hardware bien documentada para la extracción maliciosa de firmware.

Capacidades de expansión de memoria externa

Todas las reglas de expansión de memoria de programa y de datos externa definidas para el núcleo base del 8051 se aplican plenamente al microcontrolador AT89S8253. Tanto la ROM de programa como la RAM de datos pueden expandirse utilizando chips de memoria semiconductores externos con una capacidad máxima direccionable de 64 Kilobytes cada uno. El mecanismo de direccionamiento de memoria de 16 bits opera idénticamente a la arquitectura estándar original del 8051.

Modos de direccionamiento de memoria admitidos

Coherente con todos los microcontroladores estándar compatibles con 8051, se implementan dos modos distintos de direccionamiento de memoria dentro del conjunto de instrucciones de la CPU:

  • Direccionamiento directo (sintaxis de instrucción de ejemplo: MOV A,30h); y
  • Direccionamiento indirecto (sintaxis de instrucción de ejemplo: MOV A,@R0).

La comprensión integral de estos dos modos de direccionamiento es crítica para el diseño de defensa de seguridad embebida. Los mecanismos de direccionamiento indirecto presentan un vector de explotación prominente: si un atacante corrompe el valor del puntero almacenado dentro de los registros de direccionamiento indirecto R0/R1, pueden redirigir las operaciones de lectura de memoria para acceder a regiones de memoria protegidas que normalmente están bloqueadas mediante las restricciones del direccionamiento directo. Esta clase de exploits de corrupción de memoria se aprovecha con frecuencia para extraer binarios de firmware bloqueados cuando el acceso directo a la memoria está bloqueado por los fusibles de bloqueo de hardware.

4.4 Registros de Funciones Especiales (SFR)

El AT89S8253 incorpora un total de 40 Registros de Funciones Especiales únicos. Para mantener la compatibilidad total hacia atrás con las generaciones heredadas del microcontrolador 8051, el conjunto central de 22 registros fundamentales del sistema conserva direcciones de memoria y comportamiento funcional idénticos en todas las variantes de la familia. Los SFR suplementarios restantes se agregaron para proporcionar control sobre los módulos periféricos de hardware extendidos del AT89S8253 introducidos en este diseño derivado actualizado.

SFR (Registros de Funciones Especiales)

Como se visualiza en el diagrama del mapa de memoria SFR, cada registro recibe un desplazamiento de dirección RAM fijo único. Los espacios de direcciones reservadas no utilizados se asignan para futuras revisiones de silicio y nunca deben utilizarse para el almacenamiento de variables definidas por el usuario. Como implican sus nombres, cada SFR gobierna la operación de un subcircuito periférico de hardware dedicado, incluidos temporizadores, UART e interfaces SPI, todos los cuales reciben cobertura detallada dedicada más adelante en este capítulo. Esta sección solo revisa los registros SFR centrales de todo el sistema que controlan múltiples módulos de hardware independientes simultáneamente.

Entre todos los periféricos SFR extendidos, el registro de control EEPROM EECON representa el bloque de control periférico más relevante para la seguridad, ya que gobierna todos los permisos de acceso de lectura/escritura al banco de almacenamiento no volátil EEPROM interno. Un adversario capaz de afirmar el bit EEMEN dentro de EECON puede utilizar la secuencia de instrucciones MOVX para volcar por completo todo el espacio de direcciones EEPROM, eludiendo efectivamente las protecciones de los bits de bloqueo de hardware por completo. Este defecto de diseño de hardware sin parchear es una debilidad crítica bien documentada presente en múltiples variantes de microcontroladores derivados del 8051. De manera similar, el registro de control del temporizador watchdog WDTCON gobierna la lógica de reinicio de detección de manipulación; sin embargo, los atacantes pueden deshabilitar la operación del contador del watchdog mediante fluctuaciones precisas de reloj o escrituras directas de registros SFR si los registros de control del watchdog permanecen desprotegidos por las restricciones de bloqueo. Los fusibles de bit de bloqueo de hardware y la lógica de reinicio por tiempo de espera del watchdog operan como barreras de seguridad multicapa complementarias diseñadas para elevar la complejidad de la clonación de dispositivos y la ingeniería inversa de firmware. Desafortunadamente, ningún primitivo de seguridad de hardware individual ofrece resistencia absoluta a la manipulación, ya que la decapsulación del silicio puede exponer y alterar físicamente los estados de los fusibles de seguridad para neutralizar las protecciones de bloqueo. Esta limitación crítica ha impulsado el desarrollo de hardware moderno de microcontroladores seguros que integran blindaje metálico activo y circuitos sensores de detección de manipulación dedicados.

Registro Acumulador (ACC / A)

El Acumulador, referenciado a través de las etiquetas ACC o la abreviatura A, es un registro central fundacional inherente a todos los núcleos de CPU de la familia 8051. Ninguna modificación de hardware interno altera la funcionalidad fundamental de almacenamiento de datos de ancho de byte de este registro.

ACC (Acumulador)

Registro B

El registro B también constituye un registro de CPU estándar central del 8051 con características de operación bit a bit sin modificar. Este registro sirve exclusivamente como almacenamiento de operando secundario durante los ciclos de ejecución de instrucciones aritméticas de multiplicación (MUL) y división (DIV) de 8 bits.

Registro B

Registro PSW (Registro de Palabra de Estado del Programa)

El registro de Palabra de Estado del Programa es un SFR central obligatorio del 8051 con definiciones de bits de bandera y comportamiento operativo inalterados.

Registro PSW (Palabra de Estado del Programa)

Registro SP (Registro Puntero de Pila)

El registro Puntero de Pila es un SFR estándar central del 8051 con funcionalidad bit a bit fija sin modificar.

Registro SP (Puntero de Pila)

Registros de puertos de E/S P0, P1, P2, P3

Cada bit individual dentro de estos cuatro registros de puerto corresponde directamente a un pin físico de E/S que comparte el mismo identificador numérico. Estos registros facilitan la transferencia bidireccional de datos entre la lógica interna de la CPU y el hardware de circuito externo desplazando los valores de byte hacia los pines del puerto o fijando los niveles de tensión de los pines entrantes de vuelta en la memoria del registro. Los cuatro registros de puerto pertenecen al conjunto SFR central base del 8051 con funcionalidad de bits nativa sin modificar.

Registros P0, P1, P2, P3

Bancos de registros de trabajo R0 a R7

Los ocho registros de trabajo R0–R7 forman parte del diseño de memoria central estándar del 8051 con comportamiento de almacenamiento de bits sin modificar.

Registros R (R0 - R7)

Registro AUXR (Registro de Control Auxiliar)

El SFR auxiliar AUXR contiene solo dos bits de control funcionales modificables por el usuario:

Registro AUXR (Registro Auxiliar)
  • DISALE
    • 0 – El pin ALE emite pulsos continuamente a una tasa de 1/6 de la frecuencia del reloj del oscilador principal.
    • 1 – El pin ALE solo genera pulsos de estroboscopio activos exclusivamente durante la ejecución de instrucciones de acceso a memoria MOVX o MOVC.
  • Intel_Pwd_Exit
    • 0 – Al operar en el modo de bajo consumo Power-Down, la ejecución de la CPU se reanuda ante una transición de tensión de alto a bajo (1→0) en la fuente de disparo de activación externa.
    • 1 – Al operar en el modo de bajo consumo Power-Down, la ejecución de la CPU se reanuda ante una transición de tensión de bajo a alto (0→1) en la fuente de disparo de activación externa.

Registro CLKREG (Registro de Control del Multiplicador de Reloj X2)

Registro CLKREG (Registro de Reloj) X2
  • 0 – La frecuencia del oscilador externo XTAL se divide por un factor de dos antes de suministrar la lógica de reloj de la CPU; un ciclo de máquina completo consume seis períodos de reloj dividido.
  • 1 – La señal cruda del oscilador de cuarzo impulsa directamente la circuitería del reloj de la CPU. Esta característica permite la utilización de un oscilador de cristal con la mitad de la frecuencia nominal (por ejemplo, un cristal de 6 MHz en lugar de un oscilador estándar de 12 MHz) manteniendo el mismo rendimiento de ejecución de instrucciones del núcleo.
```html

Punteros de datos

Los punteros de datos no son registros físicos de hardware. Se componen de dos registros separados de 8 bits: DPH (Byte Alto del Puntero de Datos) y DPL (Byte Bajo del Puntero de Datos). El ancho completo de 16 bits del puntero de datos se utiliza para direccionar la RAM externa y la EEPROM interna en el chip. El bit DPS dentro del registro de función especial EECON selecciona qué par de registros puntero estará activo para las operaciones de direccionamiento de memoria:

DPS=0 - El puntero de datos de 16 bits activo está formado por DP0L y DP0H, denominado DPTR0.

Punteros de Datos 0

DPS=1 - El puntero de datos de 16 bits activo está formado por DP1L y DP1H, denominado DPTR1.

Punteros de Datos 1

La característica de conmutación del doble puntero de datos ofrece una cómoda conmutación de direcciones en tiempo de ejecución, sin embargo expande la superficie de ataque del MCU. Un adversario con la capacidad de manipular el bit DPS puede redirigir los accesos de lectura/escritura EEPROM a desplazamientos de memoria arbitrarios, exponiendo potencialmente los bits de bloqueo de seguridad y los fusibles de protección. En los flujos de trabajo de ingeniería inversa de hardware, este mecanismo de conmutación de punteros se abusa comúnmente para volcar los bytes de configuración de seguridad que gobiernan la protección de bloqueo de memoria.

Manejo de la memoria EEPROM

Este microcontrolador integra 2 KB de EEPROM no volátil en el chip, diseñada para almacenar datos generados en tiempo de ejecución que deben persistir a través de la pérdida de alimentación. Todos los valores escritos en la EEPROM conservan su estado después de que la alimentación se desconecta, con una resistencia mínima nominal de 100,000 ciclos de borrado-escritura. La configuración de la interfaz EEPROM se simplifica mediante un pequeño conjunto de bits de control dedicados dentro del registro EECON.

Todas las transacciones de lectura y escritura EEPROM se rigen por el registro de función especial EECON. La programación EEPROM de un solo byte tiene una latencia relativamente lenta de aproximadamente 4 milisegundos por byte, por lo que se implementa un mecanismo de aceleración de buffer de hardware para impulsar el rendimiento de escritura en lote. Cuando el bit EELD en EECON está afirmado, los datos salientes se almacenan en buffer en una memoria temporal de 32 bytes en lugar de comprometerse inmediatamente a la matriz EEPROM. Una vez que EELD se limpia, la operación de escritura única subsiguiente vaciará el contenido completo del buffer a las celdas físicas EEPROM junto con el nuevo byte. Esta operación por lotes reduce la latencia total de escritura de 32 bytes de 128 ms (32 × 4 ms) a un único ciclo de programación de 4 ms.

El espacio de memoria EEPROM comparte el mismo pipeline de direccionamiento que la RAM de datos externa. Por esta razón, la instrucción estándar de acceso a memoria externa MOVX se reutiliza para realizar operaciones de lectura/escritura tanto de EEPROM como de RAM externa. El bit de control EEMEN dentro de EECON determina el espacio de memoria objetivo para las operaciones MOVX: RAM externa o EEPROM interna. Si la dirección objetivo supera el límite de 2 KB de EEPROM mientras EEMEN está activo, el hardware enruta automáticamente el acceso a la memoria externa en su lugar.

Si bien este esquema de acceso a memoria unificado mejora la flexibilidad de desarrollo, introduce una vulnerabilidad de seguridad crítica. Si un atacante gana la capacidad de activar el bit EEMEN a 1 lógico, pueden aprovechar las instrucciones MOVX para leer y sobrescribir directamente el contenido EEPROM interno, eludiendo por completo las protecciones de bloqueo de memoria. Esto requiere protección de escritura para el registro EECON después de que los bits de bloqueo del dispositivo se activen. Muchos desarrolladores embebidos pasan por alto este paso de protección, dejando el registro EECON accesible a la modificación en tiempo de ejecución y haciendo al MCU vulnerable a ataques completos de extracción de firmware.

Manejo de la memoria EEPROM

Registro EECON

Cada campo de bits dentro del registro EECON controla comportamientos operativos distintos del módulo EEPROM integrado:

Registro EECON

WRTINH

El bit WRTINH es de solo lectura. Cuando la tensión de alimentación cae por debajo del umbral mínimo requerido para una programación EEPROM confiable, el hardware limpia automáticamente esta bandera, bloqueando nuevos ciclos de escritura y abortando cualquier operación de programación en curso.

RDY/BSY

El bit RDY/BSY funciona como una bandera de estado de solo lectura:

  • 0 - Ciclo de programación EEPROM en curso (duración típica de 4 ms).
  • 1 - Operación de programación completa; los datos han sido comprometidos a las celdas de almacenamiento EEPROM.

DPS

  • 0 - Los punteros de dirección de lectura/escritura EEPROM utilizan el par de registros DP0H y DP0L (DPTR0).
  • 1 - Los punteros de dirección de lectura/escritura EEPROM utilizan el par de registros DP1H y DP1L (DPTR1).

EEMEN

  • 0 - Todas las instrucciones MOVX apuntan a la memoria de datos externa fuera del chip.
  • 1 - Todas las instrucciones MOVX apuntan a la matriz EEPROM interna en el chip; las direcciones que superan el límite de 2 KB de EEPROM se redirigen a la memoria externa automáticamente.

El bit EEMEN representa el vector de ataque principal para el volcado EEPROM no autorizado. Cualquier adversario capaz de afirmar este bit puede ejecutar ciclos de lectura MOVX secuenciales para extraer el conjunto completo de datos EEPROM, incluidos identificadores de serie, claves secretas criptográficas y parámetros de configuración de seguridad del dispositivo. Este bit es un objetivo principal durante la ingeniería inversa de dispositivos bloqueados. La mitigación de hardware requiere la configuración permanente de los bits de bloqueo para bloquear todas las escrituras al registro EECON, sin embargo muchas implementaciones de producto omiten esta salvaguarda. La recuperación de secretos propietarios del dispositivo con frecuencia se basa en explotar este bit desprotegido para leer las regiones de memoria no volátil protegidas.

EEMWE

Cuando se afirma, el bit EEMWE habilita el acceso de escritura a la matriz EEPROM a través de instrucciones MOVX. El software debe limpiar explícitamente esta bandera inmediatamente después de completar cada transacción de escritura EEPROM.

EELD

Afirmar el bit EELD activa el buffer de escritura por lotes de 32 bytes para la programación EEPROM acelerada en masa. Mientras EELD permanezca alto, los comandos de escritura MOVX pueblan el buffer temporal de hardware en lugar de comprometer datos directamente a las celdas EEPROM. Los desarrolladores deben limpiar EELD antes de transmitir el byte de datos final en una secuencia por lotes. La ejecución de la operación MOVX concluyente desencadena un vaciado automático de hardware de todo el buffer en la memoria EEPROM física durante una única ventana de programación de 4 ms.

El mecanismo de escritura en buffer EELD proporciona ganancias sustanciales de rendimiento para las operaciones de almacenamiento de múltiples bytes, sin embargo introduce una vulnerabilidad de inyección de fallos. Los atacantes que pueden inyectar fluctuaciones precisas de reloj o tensión para interrumpir la secuencia de limpieza de EELD pueden inducir escrituras EEPROM parciales e incompletas. Este estado de memoria inconsistente puede explotarse para eludir las protecciones de bloqueo del dispositivo, formando la base de metodologías avanzadas combinadas de ataque por temporización e inyección de fallos de hardware.

4.5 Temporizador Watchdog (WDT)

El temporizador watchdog deriva su señal de reloj del oscilador de cristal principal. Se establece por defecto en un estado deshabilitado después del reinicio del sistema y detiene automáticamente el conteo durante el modo de bajo consumo Power Down, sin ejercer influencia sobre el flujo normal del programa mientras está inactivo. Una vez habilitado, el watchdog incrementa continuamente su contador interno; al desbordarse, el hardware desencadena un reinicio completo del microcontrolador, reiniciando la ejecución del programa desde la dirección del vector de reinicio inicial. La condición de reinicio del watchdog señala la ejecución anormal, detenida o corrupta del firmware. Los desarrolladores implementan instrucciones periódicas de refresco del watchdog en puntos clave del código de la aplicación para prevenir reinicios no intencionados. Toda la configuración y el comportamiento en tiempo de ejecución del temporizador watchdog se gestionan a través de campos de bits individuales dentro del registro de función especial WDTCON.

Tres bits de control de preescalador dedicados (PS2, PS1, PS0) establecen el parámetro funcional central del watchdog: el intervalo nominal de tiempo de espera de desbordamiento, que define la longitud completa del ciclo del contador antes de la activación del reinicio.

Los valores de tiempo de espera listados en la tabla siguiente se aplican exclusivamente cuando el oscilador de cristal del sistema opera a 12 MHz.

Bits del preescalador Tiempo nominal
PS2 PS1 PS0
0 0 0 16ms
0 0 1 32ms
0 1 0 64ms
0 1 1 128ms
1 0 0 256ms
1 0 1 512ms
1 1 0 1024ms
1 1 1 2048ms

Registro WDTCON (Registro de Control del Watchdog)

WDTCON (Registro de Control del Watchdog)

PS2,PS1,PS0

Estos tres bits configuran el preescalador del watchdog y determinan la ventana nominal de tiempo de espera de desbordamiento. Si el código de la aplicación no limpia la bandera de refresco WSWRST dentro de este intervalo, el contador del watchdog se desborda y afirma un reinicio completo del MCU. Cuando los tres bits del preescalador están limpios a cero, el tiempo de espera del watchdog es igual a 16,000 ciclos de máquina; cuando los tres bits están activados a uno lógico, el tiempo de espera se extiende a 2,048,000 ciclos de máquina.

WDIDLE

El bit WDIDLE conmuta la actividad de conteo del watchdog durante el modo de bajo consumo Idle:

  • 0 - El temporizador watchdog permanece activo y continúa contando mientras el MCU opera en el modo de bajo consumo Idle.
  • 1 - El temporizador watchdog suspende el conteo durante el modo Idle.

DISRTO

El bit DISRTO controla si los reinicios iniciados por el watchdog impulsan una señal lógica externa en el pin de hardware RST para reiniciar la circuitería periférica conectada:

  • 0 - El reinicio del watchdog anula el buffer de entrada del pin RST para impulsar temporalmente un pulso de salida lógico alto. Esta señal reinicia tanto el microcontrolador como todos los circuitos externos conectados a la línea RST.
  • 1 - Los reinicios internos activados por el watchdog no tienen efecto sobre el pin RST, que permanece configurado como entrada digital durante toda la secuencia de reinicio.

HWDT

El bit HWDT selecciona entre modos operativos de watchdog bloqueados por hardware y controlables por software:

  • 0 - El watchdog opera en modo software; la activación y desactivación están completamente controladas a través del bit WDTEN.
  • 1 - El watchdog opera en modo de bloqueo de hardware. Habilitar el watchdog requiere escribir la secuencia hexadecimal 0x1E seguida de 0xE1 en el registro WDTRST. Solo un reinicio completo de hardware puede deshabilitar el watchdog una vez activado. Para prevenir los reinicios por desbordamiento en modo hardware, la secuencia de refresco 0x1E / 0xE1 debe transmitirse repetidamente a WDTRST a intervalos regulares.

WSWRST

Afirmar la bandera WSWRST refresca y reinicia el contador del watchdog cuando el temporizador opera en modo software (HWDT=0). El software de la aplicación debe limpiar este bit periódicamente para mantener la operación ininterrumpida del MCU. Una vez que WSWRST se activa, el hardware automáticamente pone a cero el contador del watchdog y auto-limpia la bandera WSWRST.

Escribir en el bit WSWRST no produce ningún efecto funcional sobre el conteo del watchdog cuando el temporizador corre en modo hardware (HWDT=1).

WDTEN

El bit WDTEN habilita o deshabilita el temporizador watchdog exclusivamente durante la operación en modo software (HWDT=0):

  • 0 - Contador del watchdog deshabilitado.
  • 1 - Contador del watchdog habilitado y activo.

Cuando el watchdog está bloqueado en modo hardware (HWDT=1), el bit WDTEN se vuelve de solo lectura, reflejando el estado activo/inactivo actual del contador del watchdog.

Nota

El bit WDTEN solo conmuta el estado de activación y no reinicia el valor del contador del watchdog. El contador conserva su valor de conteo actual mientras WDTEN permanezca limpio a cero lógico.

Desde una perspectiva de ingeniería de seguridad, el temporizador watchdog sirve como una contramedida contra los ataques de volcado de memoria y sondeo. Si un adversario intenta detener el núcleo del microcontrolador para leer el contenido de la memoria interna, un watchdog activo forzará un reinicio inmediato del chip, eliminando las oportunidades de una extracción de memoria completa y limpia. Sin embargo, los atacantes obtienen tiempo suficiente para realizar operaciones completas de lectura si el watchdog está deshabilitado o configurado con una ventana de tiempo de espera excesivamente larga. Las prácticas seguras de diseño de firmware exigen configurar el watchdog con un tiempo de espera nominal corto y habilitar el modo de bloqueo de hardware, que bloquea la desactivación del watchdog a nivel de software para obstaculizar los intentos no autorizados de extracción de firmware.

4.6 Interrupciones

El microcontrolador AT89S8253 implementa seis fuentes distintas de interrupción de hardware, permitiendo al núcleo pausar la ejecución regular del programa para atender seis eventos asíncronos únicos. Cada canal de interrupción individual puede enmascararse o desenmascararse independientemente utilizando bits dedicados dentro del registro de función especial IE (Habilitación de Interrupciones), mientras que todo el sistema global de interrupciones puede deshabilitarse por completo limpiando el bit de habilitación global EA dentro del mismo registro IE.

Este dispositivo integra los módulos periféricos Temporizador T2 y SPI, que se extienden más allá de la arquitectura estándar original del 8051 y cada uno genera solicitudes de interrupción dedicadas. Estos periféricos requirieron modificaciones menores al diseño del registro de control de interrupciones, junto con una nueva dirección de vector de interrupción dedicada en 0x2B para los eventos de desbordamiento/captura del Temporizador T2. Todos los cambios arquitectónicos reutilizan posiciones de bits reservadas previamente no utilizadas dentro de los SFR existentes, asegurando la compatibilidad total hacia atrás con el firmware heredado del 8051 sin modificaciones del código fuente. Esta compatibilidad hacia atrás es un factor principal detrás de la adopción industrial generalizada de las familias de microcontroladores basados en 8051.

Interrupciones

Registro IE (Registro de Habilitación de Interrupciones)

Registro IE (Habilitación de Interrupciones)

El bit EA actúa como un interruptor maestro global para todas las fuentes de solicitud de interrupción:

  • 0 - Todas las solicitudes de interrupción se ignoran globalmente, incluso si los bits de habilitación de canales individuales están afirmados.
  • 1 - Los canales de interrupción individuales operan según sus bits de habilitación dedicados.

El bit ET2 controla el enmascaramiento de los eventos de interrupción del Temporizador T2:

  • 0 - Generación de interrupción del Temporizador T2 deshabilitada.
  • 1 - Generación de interrupción del Temporizador T2 habilitada.

El bit ES habilita o deshabilita las interrupciones combinadas de comunicación serie para los periféricos UART y SPI:

  • 0 - Interrupciones de transmisión/recepción UART y de transferencia SPI deshabilitadas.
  • 1 - Interrupciones serie UART y SPI activas y habilitadas.

El bit ET1 controla el enmascaramiento de la interrupción del Temporizador T1:

  • 0 - Interrupción de desbordamiento del Temporizador T1 deshabilitada.
  • 1 - Interrupción de desbordamiento del Temporizador T1 habilitada.

El bit EX1 gobierna las señales de interrupción externas recibidas en el pin de hardware INT1:

  • 0 - Interrupciones activadas por flanco/nivel en el pin INT1 ignoradas.
  • 1 - Solicitudes de interrupción externas en INT1 reconocidas y procesadas.

El bit ET0 habilita o deshabilita las interrupciones de desbordamiento del Temporizador T0:

  • 0 - Generación de interrupción del Temporizador T0 deshabilitada.
  • 1 - Generación de interrupción del Temporizador T0 habilitada.

El bit EX0 controla las solicitudes de interrupción externas que llegan al pin de hardware INT0:

  • 0 - Señales de interrupción externas en INT0 enmascaradas.
  • 1 - Eventos de interrupción externos en INT0 aceptados y atendidos.

Las rutinas de servicio de interrupción pueden implementarse como contramedidas de detección de manipulación de hardware. Por ejemplo, una interrupción externa conectada al pin INT0 puede monitorear las fluctuaciones repentinas de la tensión de alimentación indicativas de manipulación física. Ante el disparo de la interrupción, el MCU puede borrar inmediatamente los datos criptográficos sensibles antes de que los adversarios completen las operaciones completas de lectura de memoria. Sin embargo, los actores de ataque que ganan la capacidad de deshabilitar globalmente las interrupciones o manipular los niveles de prioridad de interrupción pueden neutralizar por completo estas rutinas de respuesta a la manipulación.

Prioridades de interrupción

Cuando múltiples canales de interrupción están habilitados simultáneamente, una nueva solicitud de interrupción puede afirmarse mientras otra rutina de servicio de interrupción ya se está ejecutando. La lógica de resolución de prioridad del microcontrolador determina si se adelanta al manejador de interrupción activo o se pone en cola la solicitud entrante para su atención posterior. Los microcontroladores 8051 de generación base proporcionan dos niveles fijos de prioridad de interrupción configurados a través del registro de función especial IP.

El AT89S8253 extiende el esquema de prioridad estándar con un SFR adicional IPH (Prioridad Alta de Interrupción), soportando cuatro niveles distintos programables de prioridad de interrupción para todas las fuentes de interrupción (excluyendo la señal de reinicio de hardware no enmascarable). La jerarquía global de prioridades sigue este orden:

  1. Reinicio de hardware: Prioridad más alta; detiene todas las operaciones en curso y reinicia el sistema completo incondicionalmente.
  2. Nivel de prioridad 3 (Nivel de interrupción más alto): Solo puede ser adelantado por señales de reinicio de hardware.
  3. Niveles de prioridad 2, 1, 0 (Niveles de interrupción más bajos): Pueden ser adelantados por cualquier interrupción de mayor prioridad o por el reinicio de hardware.

El firmware normalmente configura el nivel de prioridad asignado de cada fuente de interrupción al inicio del código principal de la aplicación. El hardware hace cumplir las siguientes reglas de resolución de prioridad durante las solicitudes de interrupción concurrentes:

  • Si dos solicitudes de interrupción de niveles de prioridad diferentes llegan simultáneamente, la interrupción de mayor prioridad recibe el servicio inmediato primero.
  • Si una segunda solicitud de interrupción de prioridad igual se afirma mientras se está ejecutando un manejador de prioridad igual, la nueva solicitud se pone en cola y espera hasta que la rutina de interrupción activa complete su ejecución.
  • Si dos solicitudes de interrupción de prioridad idéntica se disparan en el ciclo exacto, el hardware selecciona el orden de servicio utilizando la clasificación de prioridad predeterminada fija a continuación:
  1. Interrupción externa INT0
  2. Interrupción de desbordamiento del Temporizador T0
  3. Interrupción externa INT1
  4. Interrupción de desbordamiento del Temporizador T1
  5. Interrupción de comunicación serie UART/SPI
  6. Interrupción de captura/desbordamiento del Temporizador T2

Registro IP (Registro de Prioridad de Interrupción)

Registro IP (Prioridad de Interrupciones)

Cada campo de bits dentro del registro IP establece el bit de prioridad de orden bajo para su canal de interrupción correspondiente.

PT2 – bit de prioridad baja de la interrupción del Temporizador T2:

  • 0 - Bit de prioridad baja = 0
  • 1 - Bit de prioridad baja = 1

PS – bit de prioridad baja de la interrupción del puerto serie:

  • 0 - Bit de prioridad baja = 0
  • 1 - Bit de prioridad baja = 1

PT1 – bit de prioridad baja de la interrupción del Temporizador T1:

  • 0 - Bit de prioridad baja = 0
  • 1 - Bit de prioridad baja = 1

PX1 – bit de prioridad baja de la interrupción externa INT1:

  • 0 - Bit de prioridad baja = 0
  • 1 - Bit de prioridad baja = 1

PT0 – bit de prioridad baja de la interrupción del Temporizador T0:

  • 0 - Bit de prioridad baja = 0
  • 1 - Bit de prioridad baja = 1

PX0 – bit de prioridad baja de la interrupción externa INT0:

  • 0 - Bit de prioridad baja = 0
  • 1 - Bit de prioridad baja = 1

Registro IPH (Prioridad Alta de Interrupción)

Registro IPH (Prioridad Alta de Interrupciones)

PT2H Bit de prioridad alta de la interrupción del Temporizador T2

PSH Bit de prioridad alta de la interrupción del puerto serie

PT1H Bit de prioridad alta de la interrupción del Temporizador T1

PX1H Bit de prioridad alta de la interrupción externa INT1

PT0H Bit de prioridad alta de la interrupción del Temporizador T0

PX0H Bit de prioridad alta de la interrupción externa INT0

Cada bit dentro del registro IPH se combina con la posición de bit correspondiente en el registro IP para generar un valor de prioridad de dos bits, creando cuatro niveles únicos de prioridad de interrupción (cinco niveles totales cuando se incluye el reinicio de hardware).

Valor del bit IP Valor del bit IPH Nivel de prioridad de interrupción asignado
0 0 Prioridad 0 (Nivel más bajo)
0 1 Prioridad 1 (Nivel bajo)
1 0 Prioridad 2 (Nivel alto)
1 1 Prioridad 3 (Nivel de interrupción más alto)

Procesamiento de interrupción

Ante la detección de una solicitud de interrupción pendiente, el hardware del microcontrolador ejecuta la siguiente secuencia fija de operaciones automáticamente:

  1. Completar la ejecución de la instrucción de máquina actualmente activa sin adelantamiento a mitad de ciclo;
  2. Empujar la dirección del contador de programa de 16 bits de la instrucción subsiguiente a la memoria de pila interna;
  3. Cargar la dirección de memoria del vector de interrupción dedicado correspondiente a la fuente de interrupción desencadenante directamente en el registro del contador de programa, redirigiendo el flujo de ejecución del núcleo a la dirección base de la rutina de servicio de interrupción asignada según lo definido en la tabla siguiente:
Bandera de la fuente de interrupción Dirección del vector de salto de interrupción (hexadecimal)
IE0 (Interrupción externa INT0) 03h
TF0 (Desbordamiento del Temporizador T0) 0Bh
IE1 (Interrupción externa INT1) 13h
TF1 (Desbordamiento del Temporizador T1) 1Bh
RI, TI, SPIF (Interrupción serie UART/SPI) 23h
TF2, EXF2 (Desbordamiento/Captura del Temporizador T2) 2Bh
Todas las direcciones de vector listadas están formateadas en notación hexadecimal

Las subrutinas dedicadas de servicio de interrupción se almacenan en cada desplazamiento de dirección de vector. En las implementaciones prácticas de firmware, estas ubicaciones de vector normalmente contienen instrucciones de salto incondicional que apuntan al código completo del manejador de interrupción ubicado en otro lugar de la memoria del programa.

4. Una vez que la subrutina de servicio de interrupción finaliza la ejecución, el hardware extrae la dirección de retorno previamente almacenada de la pila de vuelta al registro del contador de programa, y el código de la aplicación de línea principal reanuda la ejecución en el punto exacto donde fue interrumpido.

4.7 Contadores y temporizadores

Temporizadores T0 y T1

El AT89S8253 integra tres periféricos independientes de temporizador/contador designados T0, T1 y T2. Los temporizadores T0 y T1 cumplen plenamente con la especificación periférica estándar original del 8051, sin desviaciones funcionales de la implementación de arquitectura clásica.

Temporizador T2

El Temporizador 2 es un periférico de temporizador/contador de eventos de 16 bits exclusivo de las generaciones mejoradas de la familia de microcontroladores 8051, diferenciándose estructuralmente de T0 y T1 con cuatro registros de control dedicados. Dos registros, TH2 y TL2, se concatenan para formar el par principal de registros de conteo de 16 bits. Idéntico a T0 y T1, el Temporizador 2 puede operar en modo temporizador de reloj interno o en modo contador de pulsos de eventos externos. Los dos registros restantes, RCAP2H y RCAP2L, también forman un par de almacenamiento concatenado de 16 bits que actúa como registros de retención de captura/recarga automática de hardware para capturar instantáneamente los valores del contador.

La ventaja principal del Temporizador 2 en relación con T0 y T1 es el manejo simplificado de una sola instrucción de todas las operaciones de lectura e intercambio de valores. Como T0 y T1, el Temporizador 2 admite cuatro modos operativos configurables distintos detallados más adelante dentro de este capítulo.

Registros de Contadores y Temporizadores

T2CON (Registro de Control del Temporizador/Contador 2)

T2CON (Registro de Control del Temporizador/Contador 2)

Este registro de control contiene campos de bits que gobiernan todos los modos operativos y las condiciones de disparo del periférico Temporizador 2.

TF2 El hardware afirma automáticamente la bandera de desbordamiento TF2 cuando el contador de 16 bits TH2+TL2 alcanza el valor máximo y rueda a cero. El software del firmware debe limpiar manualmente esta bandera para detectar eventos de desbordamiento subsiguientes. Si se activan los bits del generador de velocidad en baudios RCLK o TCLK, los eventos de desbordamiento del contador no modifican el estado de la bandera TF2.

EXF2 La bandera EXF2 se activa por hardware siempre que una señal de flanco descendente en el pin de hardware T2EX desencadena una operación de captura o recarga automática. Esta bandera genera una solicitud de interrupción (si el enmascaramiento de interrupción está deshabilitado), con una excepción: cuando el bit DCEN dentro de T2MOD está afirmado, EXF2 pierde su funcionalidad de disparo de interrupción. El código de la aplicación debe limpiar manualmente la bandera EXF2 después de manejar los eventos relacionados.

RCLK Bit de selección del reloj de recepción que define la fuente del temporizador para la generación de velocidad en baudios de recepción del puerto serie UART:

  • 1 - El Temporizador T2 suministra la referencia de reloj para las operaciones de recepción UART.
  • 0 - El Temporizador T1 suministra la referencia de reloj para las operaciones de recepción UART.

TCLK Bit de selección del reloj de transmisión que define la fuente del temporizador para la generación de velocidad en baudios de transmisión del puerto serie UART:

  • 1 - El Temporizador T2 suministra la referencia de reloj para las operaciones de transmisión UART.
  • 0 - El Temporizador T1 suministra la referencia de reloj para las operaciones de transmisión UART.

EXEN2 Bit de habilitación de disparo externo del Temporizador 2, que integra el pin de hardware T2EX en la lógica periférica del Temporizador 2:

  • 1 - Las transiciones de tensión en el pin T2EX modifican el comportamiento de captura/recarga del Temporizador 2.
  • 0 - Toda la actividad de señales en el pin T2EX es ignorada por la lógica de hardware del Temporizador 2.

TR2 Bit de habilitación de ejecución del Temporizador 2 para activar o detener la operación de incremento/decremento del contador:

  • 1 - Lógica de conteo del Temporizador T2 activa y en ejecución.
  • 0 - Lógica de conteo del Temporizador T2 suspendida y detenida.

C/T2 Bit de selección de modo temporizador o contador de eventos para elegir la fuente de pulsos que incrementa el par de registros del contador T2:

  • 1 - El par de registros TH2/TL2 de 16 bits se incrementa con cada señal de pulso externa recibida en el pin de hardware C/T2 (modo contador de eventos).
  • 0 - El par de registros TH2/TL2 de 16 bits se incrementa utilizando los ciclos de reloj del oscilador interno (modo temporizador).

CP/RL2 Bit selector de modo captura versus recarga automática que define la dirección de transferencia de datos entre el contador y los registros de retención RCAP2:

  • 1 - Con EXEN2=1, un flanco descendente en T2EX copia el valor actual del contador TH2/TL2 en los registros de captura RCAP2H/RCAP2L (modo captura).
  • 0 - Bajo condiciones idénticas de EXEN2=1, un flanco descendente en T2EX copia los valores prealmacenados de RCAP2H/RCAP2L en TH2/TL2 (modo recarga automática).

Los temporizadores sirven casos de uso legítimos generando relojes de temporización síncronos para las interfaces de comunicación serie, sin embargo también crean superficies de ataque de seguridad explotables. Los atacantes pueden aprovechar las capacidades precisas de medición de temporizadores para registrar las diferencias de latencia de ejecución dentro de las subrutinas de algoritmos criptográficos, ejecutando ataques de canal lateral de temporización para extraer claves secretas de cifrado. Las mejores prácticas de implementación de criptografía segura exigen lógica de ejecución de tiempo constante que evite operaciones de temporizador de longitud variable dentro de los segmentos de código críticos para la seguridad para mitigar estas vulnerabilidades de fuga.

Temporizador T2 en modo Captura

Cuando el bit CP/RL2 dentro de T2CON está afirmado a uno lógico, el Temporizador 2 entra en el modo operativo de captura dedicado como se ilustra en el diagrama referenciado. En el modo captura, el valor de contador en vivo contenido dentro de TH2 y TL2 puede copiarse instantáneamente en el par de registros de retención RCAP2H/RCAP2L sin interrumpir el incremento continuo del contador. La secuencia operativa completa del modo captura opera de la siguiente manera:

Temporizador T2 en modo Captura
  1. Precargar el valor inicial de conteo de arranque en el par de registros concatenado de 16 bits TH2 más TL2.
  2. Habilitar el conteo del Temporizador T2 afirmando el bit de ejecución TR2 dentro del registro de control T2CON. Cada pulso de reloj entrante incrementa el valor del contador de 16 bits en una unidad. Cuando el par de registros alcanza su valor máximo de 16 bits de 65535, el pulso de reloj subsiguiente desencadena un evento de desbordamiento de hardware, reinicia el valor del contador a cero y reinicia la secuencia de conteo incremental desde el desplazamiento cero inicial.

Ajustes de bits de configuración del modo captura:

Ajustes del Temporizador T2 en modo Captura

Temporizador T2 en modo recarga automática

El modo de recarga automática configura el Temporizador T2 como un temporizador de 16 bits bidireccional o contador de eventos externos con recarga automática del valor gestionada por hardware ante el desbordamiento. El control de la dirección del conteo se rige por el bit DCEN dentro del registro auxiliar de modo de temporizador T2MOD. Afirmar DCEN habilita el conteo bidireccional (ascendente o descendente), con el pin de hardware T2EX seleccionando el modo de dirección activo:

Temporizador T2 en modo Recarga Automática

T2OE Habilita al Temporizador T2 a generar una señal de onda cuadrada de reloj continua e independiente en su pin de E/S dedicado.

DCEN Cuando se afirma a uno lógico, habilita la operación de conteo bidireccional (tanto incremento ascendente como decremento descendente).

Temporizador T2 en modo Recarga Automática

Como se visualiza en el diagrama anterior, el modo de recarga automática invierte la dirección de transferencia de datos en comparación con el modo captura: ante el desbordamiento del contador, los valores prealmacenados dentro de RCAP2H y RCAP2L se copian automáticamente en el par de registros del contador principal TH2/TL2 para reiniciar el valor inicial de conteo.

Los ajustes de bits de configuración del modo recarga automática se resumen en el diagrama siguiente:

Ajustes del Temporizador T2 en modo Recarga Automática

Todo el comportamiento de recarga automática unidireccional descrito previamente se aplica exclusivamente cuando el bit DCEN dentro de T2MOD permanece limpio a cero lógico. Si DCEN se afirma, el Temporizador T2 cambia a conteo bidireccional, con el estado del pin T2EX determinando la dirección activa:

T2EX = 0 → El Temporizador T2 cuenta hacia abajo (modo decremento)
T2EX = 1 → El Temporizador T2 cuenta hacia arriba (modo incremento)

Temporizador T2 en modo Recarga Automática (DCEN=1)

Durante el conteo ascendente con DCEN=1, la secuencia funcional general coincide con el modo de recarga automática unidireccional estándar con una única modificación al comportamiento operativo de la bandera EXF2.

Durante el conteo descendente con DCEN=1, una condición de desbordamiento se desencadena cuando el valor del contador TH2/TL2 coincide con el valor de recarga RCAP2H/RCAP2L. Este evento de coincidencia afirma la bandera de desbordamiento TF2 y activa todos los bits dentro de TH2 y TL2 a uno lógico, mientras el contador continúa decrementándose secuencialmente a través de los valores 65535, 65534, 65533, y así sucesivamente.

Bajo ambos escenarios de conteo bidireccional ascendente y descendente, la bandera EXF2 asume una función de hardware modificada. Ante la detección de desbordamiento, este bit conmuta su estado de señal y pierde su capacidad original de generación de interrupción. En su lugar, EXF2 actúa como un bit de acarreo adicional número 17 para el par de registros de conteo, extendiendo efectivamente el Temporizador T2 en un periférico de contador virtual de 17 bits.

Temporizador T2 como generador de velocidad en baudios

El Temporizador T2 puede operar simultáneamente como fuente de reloj de velocidad en baudios UART y generador independiente de onda cuadrada de reloj. Si se afirma el bit RCLK o TCLK dentro de T2CON, el Temporizador T2 se reconfigura en un periférico generador de velocidad en baudios dedicado, operando con lógica interna casi idéntica al modo de recarga automática estándar. La fórmula de cálculo de velocidad en baudios se muestra en el gráfico referenciado a continuación:

Fórmula de velocidad en baudios

Especificaciones operativas críticas para el modo generador de velocidad en baudios:

  1. Esta fórmula de cálculo de velocidad en baudios solo se aplica cuando el oscilador de cristal interno del MCU sirve como referencia de reloj; en el modo generador de velocidad en baudios, el reloj del oscilador se divide por un factor de dos en lugar del divisor estándar de ciclos de máquina por 12.
  2. Los eventos de desbordamiento del contador no modifican el estado de la bandera TF2 y no generarán solicitudes de interrupción para el Temporizador T2.
  3. El nivel lógico presente en el pin T2EX no tiene impacto en la operación del Temporizador T2 independientemente de la configuración del bit EXEN2. Esto libera el pin T2EX para ser utilizado como un canal de entrada de interrupción externa independiente durante la operación del generador de velocidad en baudios.
  4. El software del firmware debe deshabilitar el Temporizador T2 (TR2=0) antes de leer o escribir nuevos valores en los registros TH2 y TL2. No detener el conteo antes de la modificación del registro puede introducir errores de temporización y de trama de la comunicación serie UART.

Temporizador T2 como generador de reloj

Como se señaló previamente, el Temporizador T2 admite la funcionalidad independiente de generación de onda cuadrada de reloj. En todos los modos operativos previos, el pin de hardware P1.0 (etiquetado T2 en los diagramas de bloque) funciona como entrada de pulsos externos para el conteo de eventos del contador. Este pin puede configurarse alternativamente como controlador de salida de señal de reloj continua. Cuando se empareja con un oscilador de cristal de 16 MHz, la frecuencia de onda cuadrada de salida generada va de 61 Hz hasta 4 MHz con un ciclo de trabajo fijo del 50%.

seguridad de hardware la investigación es mejorar

el nivel general de seguridad

Fórmula de frecuencia

Para habilitar el modo de salida de reloj en el pin T2/P1.0, el bit C/T2 dentro de T2CON debe limpiarse a cero, mientras que el bit T2OE dentro del registro T2MOD debe afirmarse a uno lógico. Afirmar el bit de ejecución TR2 activa el contador del temporizador, y el pin P1.0 comienza a emitir una onda rectangular continua cuya frecuencia puede calcularse mediante la fórmula mostrada en el gráfico referenciado:

4.8 Receptor-Transmisor Asíncrono Universal (UART)

Registro SCON

El periférico UART integrado mantiene una paridad funcional completa con la implementación UART estándar encontrada en los microcontroladores 8051 base. Admite cuatro modos operativos de comunicación asíncrona distintos, seleccionados a través de los campos de bits SM0 y SM1 dentro del registro de control serie SCON.

Comunicación Multiprocesador

La interfaz de comunicación serie UART crea un vector de ataque significativo de ingeniería inversa si la protección de bloqueo de memoria del dispositivo se deja sin configurar. Los atacantes pueden monitorear pasivamente el pin de transmisión TXD para capturar los datos en texto plano sin cifrar transmitidos durante la operación normal en tiempo de ejecución. Si el producto implementa la funcionalidad de carga de firmware del bootloader basada en UART sin seguridad de bits de bloqueo activa, los adversarios pueden extraer directamente binarios completos de firmware a través de comandos de lectura del puerto serie. La configuración adecuada de los bits de bloqueo es obligatoria para bloquear estas operaciones no autorizadas de lectura de memoria.

El modo de comunicación serie multiprocesador se activa cuando el bit SM2 dentro de SCON está afirmado, habilitando el filtrado automático de direcciones por hardware para las topologías de bus serie multidrop. El hardware del puerto serie evalúa independientemente el identificador de dirección incrustado dentro de cada trama serie entrante, eliminando el requisito de que todos los microcontroladores conectados ejecuten lógica de comparación de direcciones en el firmware de la aplicación y simplificando drásticamente el desarrollo de software de redes de múltiples dispositivos. El flujo de trabajo operativo completo se detalla a continuación para mayor claridad.

Registros SADDR y SADEN

Dos registros de función especial dedicados, SADDR y SADEN, brindan una funcionalidad flexible de direccionamiento multiprocesador. Cada dispositivo esclavo almacena su dirección de identificador de hardware única dentro del registro SADDR, mientras que el registro SADEN contiene un valor de máscara de dirección programable. Los bits de máscara configurados como comodines "no importa" permiten al controlador maestro apuntar a nodos esclavos individuales o transmitir datos a múltiples dispositivos esclavos simultáneamente. En resumen, el registro de máscara SADEN define qué posiciones de bits dentro del registro de dirección esclava SADDR se evalúan durante la coincidencia de direcciones y qué bits son ignorados por la lógica de filtrado de hardware.

Cuando el controlador maestro pretende transmitir datos a un dispositivo esclavo específico en el bus serie, primero transmite un byte de trama de dirección dedicado para identificar el nodo objetivo. Los bytes de dirección se distinguen de los bytes de datos estándar por un valor de uno lógico en el noveno bit de trama, mientras que las tramas de datos llevan un noveno bit de cero lógico. Después de recibir una trama de dirección, cada esclavo conectado ejecuta una verificación de coincidencia de dirección de hardware contra su configuración SADDR/SADEN. El esclavo objetivo coincidente limpia automáticamente su bandera SM2 para habilitar la recepción de las tramas de datos subsiguientes. Todos los nodos esclavos no coincidentes conservan su bandera SM2 activada a uno lógico e ignoran todas las tramas de datos entrantes hasta que el maestro transmita un nuevo byte de dirección.

Un ejemplo simplificado de una mini-red de microcontroladores de tres nodos demuestra este esquema de direccionamiento:

Microcontroller B: SADDR = 1100 0000
                   SADEN = 1111 1101
                 Match Address Mask = 1100 00X0
                        
Microcontroller C: SADDR = 1100 0000
                   SADEN = 1111 1110
                 Match Address Mask = 1100 000X
Comunicación Multiprocesador

El microcontrolador A opera como nodo maestro, comunicándose con los dispositivos esclavos etiquetados B y C.

Aunque tanto el esclavo B como el esclavo C comparten un valor de dirección base idéntico de 1100 0000, las máscaras comodín únicas almacenadas dentro de sus respectivos registros SADEN permiten el direccionamiento individual o de difusión desde el controlador maestro:
Transmitir el byte de dirección 1100 0010 enruta los datos exclusivamente al dispositivo esclavo B.
Transmitir el byte de dirección 1100 0001 enruta los datos exclusivamente al dispositivo esclavo C.

Transmitir el byte de dirección 1100 0000 desencadena una transmisión de difusión recibida por ambos dispositivos esclavos simultáneamente.

4.9 Sistema SPI (Interfaz Periférica Serie)

Además del periférico serie asíncrono UART, el AT89S8253 integra un módulo de comunicación SPI síncrono de alta velocidad, una extensión no incluida dentro de la especificación periférica original base del 8051. La interfaz SPI habilita transferencias de datos síncronas full-duplex entre el microcontrolador anfitrión y uno o más periféricos esclavos externos, o entre múltiples dispositivos de microcontroladores interconectados. Un dispositivo en el bus SPI asume el rol de maestro exclusivamente; el maestro define la frecuencia del reloj serie, la dirección de transmisión de datos (transmitir o recibir) y el formato de trama de bits serie. Todos los dispositivos de bus restantes operan como nodos esclavos subordinados, que no pueden iniciar operaciones de transferencia de datos y deben sincronizarse completamente con los parámetros de temporización y formato establecidos por el controlador maestro activo.

Sistema SPI (Interfaz Periférica Serie)

Las transferencias de datos SPI utilizan un bus diferencial full-duplex compuesto por tres líneas de señal dedicadas mapeadas a los pines de hardware MISO (P1.6), MOSI (P1.5) y SCK (P1.7). La cuarta señal de control SPI, el pin de selección de esclavo SS, no se usa en dispositivos en modo maestro y puede reutilizarse como pin de entrada/salida digital de propósito general. Para la operación en modo esclavo, el pin SS debe mantenerse en un nivel de tensión lógico bajo para activar el periférico SPI; afirmar el pin SS alto deshabilita el módulo SPI esclavo y libera el pin MOSI para la funcionalidad de E/S general.

Nota

Como se ilustra en el diagrama esquemático, la dirección de entrada/salida de los pines MISO y MOSI se invierte entre los modos operativos de maestro y esclavo, controlada enteramente por el campo de bits MSTR dentro del registro de control SPI SPCR.
Comprender las abreviaturas de los pines de señal SPI simplifica la implementación del cableado de hardware:

MISO = Entrada de Maestro, Salida de Esclavo; MOSI = Salida de Maestro, Entrada de Esclavo; SCK = Reloj Serie; SS = Habilitación de Selección de Esclavo del Chip;

Idéntico a la mayoría de los periféricos en el chip dentro del microcontrolador, el módulo SPI admite múltiples modos operativos configurables a través de bits de registro de control dedicados.

Modo SPI normal (buffer fuera de uso)

El bus SPI actúa como la interfaz de programación de hardware principal para el AT89S8253. Si las protecciones de seguridad de los bits de bloqueo del dispositivo permanecen sin programar, los atacantes solo necesitan conectar físicamente sondas de prueba a los cuatro pines de señal SPI para realizar la lectura completa de la memoria flash y la extracción completa del firmware. Incluso con las protecciones de bits de bloqueo activadas, los ataques especializados de inyección de fallos de hardware pueden inyectar fluctuaciones precisas de reloj en la línea SCK para forzar al microcontrolador a emitir datos de memoria protegidos durante la entrada al modo de programación. Para la máxima seguridad del dispositivo, los fabricantes deben programar el nivel más alto de seguridad de bits de bloqueo, que deshabilita permanentemente toda la funcionalidad de comandos de lectura de memoria SPI.

Modo SPI normal (buffer fuera de uso)

Los bytes de datos escritos en el registro de datos SPI SPDR se transfieren automáticamente a un registro de desplazamiento de hardware interno de 8 bits. El generador de reloj SPI se activa, y los flujos de datos de bits serie salen secuencialmente en el pin de transmisión MOSI. Puede ocurrir un breve retardo de sincronización durante el arranque inicial del bus para alinear la lógica de temporización interna con el oscilador principal del MCU.

Al completarse la transmisión de un solo byte, el generador de reloj SPI se detiene automáticamente, el bit de bandera de interrupción de transferencia completa SPIF se afirma, el byte entrante recibido del dispositivo esclavo se fija en el registro SPDR, y se genera una solicitud de interrupción SPI si tanto el bit de habilitación de interrupción SPI global SPIE como el bit de habilitación de interrupción serie ES están afirmados.

Modo SPI mejorado (buffer en uso)

Intentar escribir un nuevo valor de byte en el registro SPDR a mitad de un ciclo de transmisión activo desencadena la bandera de bit de error de colisión de escritura WCOL. Esta bandera señala operaciones de escritura prematuras inválidas. El byte original en transmisión se completará exitosamente, mientras que el valor de byte recién escrito se descarta sin que ocurra ninguna transmisión.

El modo SPI mejorado con buffer comparte la lógica funcional central con el modo normal estándar, con la adición crítica de un registro de buffer de hardware intermedio entre el registro de datos SPDR y el registro de desplazamiento principal. Si bien esta etapa de almacenamiento extra parece redundante a primera vista, proporciona mejoras significativas de rendimiento para las transferencias masivas de datos de múltiples bytes, como se visualiza en el diagrama referenciado a continuación.

Modo SPI mejorado (buffer en uso)

Los datos escritos en el registro SPDR se transfieren automáticamente al registro de buffer de captura intermedio, que inmediatamente afirma el bit de bandera WCOL para indicar que la etapa de almacenamiento del buffer contiene datos pendientes. Las operaciones de escritura adicionales a SPDR mientras el buffer permanece lleno desencadenarán condiciones de colisión de desbordamiento. La lógica de hardware limpia automáticamente la bandera WCOL una vez que los datos almacenados en buffer se transfieren del buffer intermedio al registro de desplazamiento principal y comienza la transmisión serie. Si el byte escrito en SPDR es la primera trama de una secuencia de transferencia, los datos se mueven inmediatamente al registro de desplazamiento vacío, limpiando la bandera WCOL para señalar un estado de buffer vacío.

Mientras una transmisión de byte está en curso, el byte subsiguiente a enviar puede escribirse en el registro SPDR. Este nuevo byte se transferirá inmediatamente al buffer de transmisión interno. Para determinar si una operación de transmisión de datos está activa, los usuarios solo necesitan verificar el nivel lógico del bit LDEN dentro del registro SPSR. Si este bit está afirmado (Habilitación de Carga) y el bit WCOL permanece limpio, una transmisión está actualmente en ejecución y el buffer de transmisión está vacío, lo que permite escribir el siguiente byte en el registro SPDR sin conflicto.

¿Cómo seleccionar el modo SPI óptimo? Si solo se requieren transmisiones esporádicas de un solo byte, no hay necesidad de configuración compleja: el modo normal estándar sirve como la solución más directa. Cuando es necesaria la transferencia de datos masivos, el modo mejorado entrega un rendimiento superior: el oscilador de reloj interno permanece habilitado siempre que el buffer de transmisión se rellene periódicamente y la bandera WCOL se dispare. Además, este modo elimina la sobrecarga de sincronización y facilita la transmisión de datos sin fisuras de alta eficiencia.

SPDR (Registro de Datos SPI)

El periférico SPI se gestiona mediante tres registros de función especial dedicados: SPDR, SPSR y SPCR.

SPDR (Registro de Datos SPI)

SPSR (Registro de Estado SPI)

SPSR (Registro de Estado SPI)

El registro SPDR almacena los datos serie salientes para la transmisión SPI y también captura todos los datos serie entrantes recibidos. SPIF

Bandera de Interrupción SPI. Este bit se activa automáticamente al completarse una transferencia de datos de byte completo. Si tanto los bits de habilitación de interrupción SPIE como ES están activados, se generará una solicitud de interrupción SPI. La bandera SPIF se limpia leyendo consecutivamente el registro SPSR seguido de un acceso de lectura o escritura al registro SPDR. WCOL
Bandera de Colisión de Escritura. En el modo operativo normal (ENH=0), este bit se fija en alto si el firmware intenta escribir en SPDR a mitad de transmisión; tales operaciones de escritura prematuras se descartan sin impacto en las transferencias en curso, definido como un evento de Colisión de Escritura. La bandera se limpia utilizando la secuencia idéntica requerida para limpiar el bit SPIF.

En el modo mejorado (ENH=1), WCOL se afirma cuando el buffer de transmisión contiene datos pendientes válidos, señalando que los nuevos datos están listos para desplazarse al registro de desplazamiento principal para la transmisión.

  En el modo mejorado, los nuevos datos de transmisión pueden cargarse en el buffer de transmisión solo después de que la bandera WCOL haya sido limpiada. DISSO

Bit de Deshabilitación de Salida de Esclavo. Cuando se activa, este bit pone en tri-estado el pin de hardware MISO, habilitando que múltiples microcontroladores esclavos compartan una sola interfaz de bus SPI. Convencionalmente, todos los dispositivos esclavos conectados reciben el byte de dirección inicial, y solo el esclavo objetivo debe limpiar su propio bit DISSO para impulsar la línea MISO para el intercambio de datos subsiguiente.
ENH
0 Configura el periférico SPI para el modo de operación normal sin buffer de transmisión de hardware.

SPCR (Registro de Control SPI)

SPCR (Registro de Control SPI)

1 Habilita el modo operativo mejorado con buffer SPI. SPIE

Habilitación de Interrupción SPI. Afirmar este bit permite al módulo SPI generar solicitudes de interrupción de hardware al completarse la transferencia. SPE

Habilitación del Periférico SPI. Este bit activa la funcionalidad de comunicación SPI. Una vez activado, los pines de hardware SS, MOSI, MISO y SCK se multiplexan a los pines de puerto del microcontrolador P1.4, P1.5, P1.6 y P1.7 respectivamente. DORD

  • 0 Bit de Orden de Datos. Define la secuencia de transmisión de bits para las tramas serie SPI:
  • 1 – Transmitir el Bit Más Significativo (MSB) primero.

– Transmitir el Bit Menos Significativo (LSB) primero. MSTR

  • 0 Selección de Modo Maestro/Esclavo. Determina si el microcontrolador actúa como dispositivo SPI maestro o esclavo en el bus:
  • 1 – Operar como periférico esclavo SPI.

– Operar como controlador maestro de bus SPI. CPOL

  • 0 Bit de Polaridad de Reloj. Establece el estado lógico inactivo del pin de reloj SCK cuando no hay transferencia SPI activa:
  • 1 – Pin SCK mantenido en lógico bajo durante los períodos inactivos.

– Pin SCK mantenido en lógico alto durante los períodos inactivos. CPHA

Bit de Fase de Reloj. Combinado con el ajuste CPOL, este bit controla la relación de temporización relativa entre los flancos del reloj serie y el muestreo de datos. Consulte los diagramas de temporización proporcionados a continuación para referencia. SPR1,SPR0

Bits de Selección de Velocidad de Reloj SPI. Cuando el módulo SPI está configurado como maestro, estos dos bits establecen la frecuencia de velocidad en baudios del reloj serie maestro (SCK). En el modo de operación esclavo, estos bits no tienen efecto funcional; la velocidad del reloj del bus SPI está dictada completamente por el controlador maestro externo. SPR1 SPR0
0 0 Frecuencia de Reloj SCK
0 1 Fosc/4
1 0 Fosc/16
1 1 Fosc/64

Fosc/128

Formato de datos en caso CPHA=0

Diagrama de temporización de trama serie para la configuración CPHA=0

* Estado de señal indefinido; normalmente mantiene el valor MSB del byte de datos recibido previamente.

Formato de datos en caso CPHA=1

Diagrama de temporización de trama serie para la configuración CPHA=1

* Estado de señal indefinido; normalmente mantiene el valor LSB del byte de datos recibido previamente.

  • Deben seguirse dos reglas críticas durante la inicialización del periférico SPI:
  • Todos los dispositivos maestros SPI deben configurarse completamente antes de inicializar los periféricos esclavos conectados.

Al programar el registro de control SPCR, el bit de habilitación SPE SPI debe escribirse al final, después de que todos los parámetros restantes de temporización, modo e interrupción estén configurados.

4.10 Gestión del consumo de energía

Idéntico a todos los demás microcontroladores de la arquitectura 8051, este dispositivo admite tres modos operativos de alimentación distintos: Modo Normal (consumo de corriente típico ~25 mA), Modo Idle (consumo de corriente típico ~6.5 mA) y Modo Power-Down (consumo de corriente típico ~40 μA). La selección del modo operativo se controla a través de bits de bandera dedicados dentro del Registro de Control de Alimentación PCON. Tres bits de registro presentan funcionalidad modificada en comparación con las variantes base estándar del 8051:

Registro PCON

Descripción general del registro PCON

Descripción funcional de cada bit dentro del registro PCON: SMOD1

Habilitación de Doble Velocidad en Baudios UART. Cuando se afirma, este bit duplica la frecuencia de velocidad en baudios base de la comunicación serie. SMOD0

  • Selector de Función del Bit 7 del Registro SCON. Este bit redefine el propósito operativo del bit más alto dentro del registro de control serie SCON:
  • 0 El bit 7 de SCON opera como SM0 para seleccionar el modo operativo de comunicación serie UART.

1 El bit 7 de SCON funciona como la bandera de detección de Error de Trama (FE); esta configuración rara vez se implementa en el firmware de la aplicación. POF

Bandera de Reinicio por Encendido. Se activa automáticamente después de que la tensión de alimentación se eleva por encima del umbral de 3V durante el encendido inicial del dispositivo. Esta bandera permite al firmware diferenciar entre los reinicios de encendido en frío y los reinicios de activación desencadenados después de salir del modo de bajo consumo Power-Down. GF1

Bit de Bandera de Usuario de Propósito General, disponible para el almacenamiento arbitrario de firmware y el seguimiento de estado. GF1

GF0 PD

Disparador de Modo Power-Down. Escribir un 1 lógico en este bit fuerza al microcontrolador al estado operativo completo de bajo consumo Power-Down. IDL

Disparador de Modo Idle. Escribir un 1 lógico en este bit coloca al microcontrolador en el estado operativo de bajo consumo Idle.

El modo Power-Down puede aprovecharse como contramedida de seguridad de hardware: si los eventos de manipulación física son detectados por la lógica periférica, el MCU puede entrar inmediatamente al estado Power-Down para detener todos los osciladores de reloj internos, complicando significativamente los ataques de lectura de memoria por parte de actores malintencionados. Sin embargo, con una alimentación estable mantenida, los atacantes aún pueden realizar la decapsulación del chip para sondear directamente las celdas de memoria internas. El modo de alimentación Idle conlleva vulnerabilidad inherente a los ataques de fluctuación de reloj, ya que el oscilador principal permanece activo mientras el pipeline de ejecución del núcleo de la CPU está suspendido; esta condición crea oportunidades para el análisis de canal lateral para extraer datos de bus sensibles.

Solución de problemas de errores comunes de firmware

Cuando ocurre un comportamiento anormal inesperado durante la operación en tiempo de ejecución del microcontrolador, el análisis de causa raíz casi nunca apunta a defectos de hardware intrínsecos del propio MCU. Aunque no es obvio a primera vista, el microcontrolador ejecuta estrictamente cada instrucción de máquina almacenada en la memoria del programa sin desviación. Por esta razón, los desarrolladores deben tener extrema precaución alrededor de varios puntos críticos de alto riesgo durante el desarrollo del código fuente, comenzando con la gestión del diseño de la memoria RAM.

Errores comunes 01

Si bien el espacio de RAM integrado está dimensionado para satisfacer la mayoría de los requisitos de las aplicaciones embebidas e incorpora todas las regiones de memoria requeridas, todo el conjunto de RAM existe como un único bloque de memoria física contiguo. Ninguna separación de hardware aísla los bancos de registros R0–R7, la memoria scratchpad de propósito general y las regiones de almacenamiento de pila: estas particiones funcionales son meramente rangos de direcciones lógicas mapeados en el espacio de direcciones RAM unificado. Consulte el diagrama del mapa de memoria adjunto para aclaraciones.

No tener en cuenta esta arquitectura de memoria unificada introduce un riesgo severo de ejecución de programa errática e impredecible. Las siguientes precauciones de diseño mitigan tales fallas de corrupción de memoria:

Si el firmware utiliza exclusivamente los registros R0–R7 del Banco de Registros 0, las direcciones de memoria 08h a 1Fh permanecen disponibles de manera segura para el almacenamiento general de variables. Cuando se activan bancos de registros alternativos (1, 2 o 3), los desarrolladores deben evitar escribir en las direcciones de memoria por debajo de 20h, ya que tales accesos arriesgan sobrescribir el contenido de los registros R del banco activo y corromper el estado en tiempo de ejecución.

Si el código fuente de la aplicación no implementa variables booleanas direccionables por bits, el rango de direcciones de memoria 20h–2Fh puede asignarse libremente para el almacenamiento de datos. El firmware que emplea variables de bits debe tener cuidado estricto al modificar las direcciones en este rango para prevenir la corrupción accidental de las banderas de bits almacenadas.

Por defecto, el puntero de pila inicializa el almacenamiento de pila comenzando en la dirección de memoria 08h. La activación de los Bancos de Registros 1, 2 o 3 sobrescribirá sus valores de registro con las operaciones de empuje de pila. La mejor práctica de la industria dicta reinicializar el registro Puntero de Pila a una dirección mayor que 20h (o superior) al comienzo mismo del flujo de ejecución del programa principal.

Los Registros de Funciones Especiales (SFR) proporcionan interfaces de control de periféricos de hardware dedicados, cada uno asignado con una función predefinida única. Las direcciones SFR no pueden reutilizarse como memoria scratchpad de propósito general, incluso si existen posiciones de bits no utilizadas dentro de los bytes de registro individuales.

El conjunto de instrucciones nativo del microcontrolador admite operaciones directas de manipulación de bits dirigidas a todas las direcciones de byte de 20h a 7Fh en la RAM interna. Además, un subconjunto de Registros de Funciones Especiales admite el acceso directo de un solo bit; solo los SFR asignados a direcciones base divisible uniformemente por ocho califican para la capacidad de direccionamiento bit a bit.

Cuando se conecta hardware de expansión de RAM externa o ROM de programa externa, el Puerto 0 y el Puerto 2 se convierten en líneas de bus de direcciones/datos dedicadas permanentemente y no pueden reutilizarse para E/S digital general, independientemente de cuántos pines físicos estén conectados eléctricamente a los chips de memoria externos.

El puntero de datos DPTR es un registro compuesto de 16 bits dividido en dos segmentos independientes de 8 bits: DPH (byte alto) y DPL (byte bajo). Todas las operaciones de pila y memoria deben tratar a DPTR como esta estructura de dos partes. Como ejemplo, al empujar el valor completo de DPTR a la pila del sistema, el byte bajo DPL debe empujarse primero, seguido del byte alto DPH.

Los periféricos de comunicación serie UART se configuran completamente a través del registro de control serie SCON. La configuración suplementaria de los registros de configuración de temporizadores TCON y TMOD también es obligatoria, ya que el Temporizador 1 sirve como el generador principal de reloj de velocidad en baudios para la operación UART estándar.

Habilitar la funcionalidad de interrupción de hardware introduce un riesgo sustancial de bloqueos de programa no deterministas si se omiten los protocolos adecuados de preservación de contexto. Al recibir una señal de solicitud de interrupción, el microcontrolador completa la ejecución de la instrucción de máquina actualmente activa, empuja la dirección del contador de programa de retorno a la pila para reanudar el código principal más tarde, luego salta la ejecución a la dirección del vector de la rutina de servicio de interrupción asignada. Una vez que la rutina de interrupción finaliza, el MCU extrae la dirección de retorno almacenada de la pila y reanuda la ejecución del código de aplicación principal. Sin embargo, una supervisión crítica introduce con frecuencia fallas catastróficas en tiempo de ejecución:

  • La pila de hardware solo preserva la dirección de retorno del contador de programa para la reanudación post-interrupción. Numerosos registros centrales tendrán sus valores modificados durante la ejecución de la rutina de servicio de interrupción. Si los estados originales de los registros no se guardan y restauran antes de salir del manejador de interrupción, la lógica principal de la aplicación operará utilizando datos de registro corruptos, desencadenando inestabilidad completa del programa. Esta condición de falla puede manifestarse inmediatamente ante el disparo de la interrupción o permanecer latente durante días dependiendo de la temporización de los eventos de interrupción. La resolución definitiva requiere guardar todo el contexto crítico de registros al inicio de cada rutina de servicio de interrupción y restaurar los valores originales de los registros antes de ejecutar la instrucción de retorno de interrupción. Los registros que requieren respaldo de contexto obligatorio incluyen:
  • PSW Palabra de Estado del Programa
  • DPTR registro puntero compuesto (bytes individuales DPH y DPL)
  • ACC registro Acumulador
  • B registro auxiliar de Multiplicador/Divisor

R0 a R7 registros de propósito general en bancos Register context preservation is conventionally implemented with PUSH stack instructions. Direct mnemonics such as PUSH R0 cannot be utilized for banked register storage. The microcontroller hardware cannot resolve which physical register bank corresponds to the generic R0–R7 label, as four independent banks share identical register naming. Instead, developers must push the absolute RAM base address of each target register (for example, PUSH 00h to save Bank 0 R0) onto the stack.

Nota importante:

Al ejecutar instrucciones de direccionamiento indirecto a través de los punteros R0/R1, evite usar estas operaciones para acceder a los Registros de Funciones Especiales. El hardware del microcontrolador ignora el mapeo de memoria SFR durante el acceso indirecto y en su lugar apunta a ubicaciones de RAM interna que comparten direcciones de byte idénticas con los SFR, causando escrituras de datos no intencionadas a la memoria scratchpad.

La bandera de transmisión completa UART (TI) y la bandera de recepción completa (RI) dentro del registro SCON generan un único vector de interrupción compartido. Cuando esta interrupción UART combinada se dispara, el firmware debe sondear ambas banderas para identificar la fuente de la interrupción: finalización de transmisión, finalización de recepción, o eventos simultáneos de transmisión/recepción. Los desarrolladores deben limpiar manualmente las banderas TI y RI mediante lógica de software después de manejar el evento de interrupción correspondiente; dejar cualquiera de las banderas afirmada crea un bucle de interrupción infinito donde la misma rutina de servicio se ejecuta continuamente sin salida.

Estos errores de codificación de firmware generalizados conllevan vulnerabilidades de seguridad embebidas tangibles. Por ejemplo, la corrupción de pila dentro de un manejador de interrupción puede desencadenar saltos incontrolados del contador de programa a direcciones de memoria arbitrarias, creando superficies de ataque explotables para la inyección de código ejecutable malicioso. En los sistemas embebidos seguros bloqueados, tales errores de corrupción de memoria pueden deshabilitar inadvertidamente los mecanismos de protección contra manipulación si las direcciones de la tabla de vectores de interrupción se sobrescriben. Las prácticas rigurosas de codificación defensiva son por lo tanto esenciales para eliminar las debilidades explotables que simplifican la ingeniería inversa y los esfuerzos de hacking de hardware.

Listado completo de Registros de Funciones Especiales direccionables por bits

Registro Acumulador (Dirección base: E0h)
ACC 0 0 0 0 0 0 0 0
Valor posterior al reinicio Designador de bit Designador de bit Designador de bit Designador de bit Designador de bit Designador de bit Designador de bit Designador de bit
- Dirección de bit absoluta E7 E6 E5 E4 E3 E2 E1
  • E0
  • Lista de ingeniería inversa de MCU SyncMOS 8051 de Mikatech:

    Protección de hackeo de microcontroladores de la serie F29Cxx: F29C31004T F29C31004B F29C31400TF29LC51002F29LC51001F29LC51000 F29C51004T F29C51002T F29C51001T F29C51000T F29C51000B F29C51004T F29C51004B F29C51002T F29C51002B F29C51001T F29C51001BF29C61400T ...

    Protección de firmware de hackeo de controladores de la serie S29Cxx: S29C31001B S29C31001T S29C31002B S29C31002T S29C31004B S29C31004T S29C51001B S29C51001T S29C51002B S29C51002T S29C51004B S29C51004T ...

    Protección de lectura de microcontroladores de la serie MSUxx: MSU1958 MSU2952 MSU2964 MSU2958 ...

    Protección de bit de bloqueo de hackeo de controladores de la serie SM29xx: SM2951 SM2952 SM2954 SM2958 SM2964 SM2965 ...

    Protección de bit de bloqueo de lectura de microcontroladores de la serie SM59xx: SM59064 SM59128C SM59128L SM5912C SM5912L SM5916C SM59164 SM5916L SM59264 SM5964 SM5964A SM5964AC SM5964AL SM5964C SM5964D0 SM5964D0A SM5964D1A SM59D02G2C SM59D02G2L SM59D03G2C SM59D03G2L SM59D04G2C SM59D04G2L SM59R08A2 ...

    Protección de hackeo de microcontroladores de la serie SM59xx: SM7908 SM79108 SM79164 SM79164L SM79164V SM7932 SM7964 ...

Protección de bit de bloqueo de hackeo de controladores de la serie SM59xx: SM894051 SM8951 SM89516 SM89516A SM89516AL SM89516B SM89516BL SM89516L SM8951A SM8951AL SM8951B SM8951BL SM8951L SM8952 SM8952A SM8952AL SM8952B SM8952BL SM8952L SM8954 SM8954A SM8954AL SM8954B SM8954BL SM8954L SM8958 SM8958A SM8958AL SM8958B SM8958BL SM8958L SM89S16R1C SM89T04R1C SM89T04R1L SM89T08R1C SM89T08R1L SM89T16R1C SM89T16R1L ..




    tiempo_de_hackeo_de_microcontrolador

    Ingeniería inversa de MCU Zilog

    Años 28
    países de hackeo de microcontroladores

    +

    Países 28
    clientes de ataque de microcontroladores

    110

    Clientes 28
    proyectos de microcontroladores desbloqueados

    5000

    Proyectos 28