El conjunto de instrucciones Atmel AVR es el lenguaje de máquina para el Atmel AVR , un microcontrolador de un solo chip RISC de 8 bits con arquitectura Harvard modificada que fue desarrollado por Atmel en 1996. El AVR fue una de las primeras familias de microcontroladores en utilizar memoria flash en chip para el almacenamiento de programas.
Hay 32 registros de 8 bits de propósito general, R0–R31. Todas las operaciones aritméticas y lógicas operan en esos registros; solo las instrucciones de carga y almacenamiento acceden a la RAM.
Un número limitado de instrucciones funcionan en pares de registros de 16 bits. El registro de menor número del par contiene los bits menos significativos y debe ser par. Los últimos tres pares de registros se utilizan como registros de puntero para el direccionamiento de memoria. Se conocen como X (R27:R26), Y (R29:R28) y Z (R31:R30). Los tres admiten los modos de direccionamiento de postincremento y predecremento. Y y Z también admiten un desplazamiento positivo de seis bits.
Las instrucciones que permiten un valor inmediato están limitadas a los registros R16–R31 (operaciones de 8 bits) o a los pares de registros R25:R24–R31:R30 (operaciones de 16 bits ADIW y SBIW). Algunas variantes de la operación MUL están limitadas a ocho registros, R16 a R23.
Además de estos 32 registros de propósito general, la CPU tiene algunos registros de propósito especial:
Los bits del registro de estado son:
Hay dos casos especiales que existen para facilitar la aritmética de múltiples bytes:
INC
y no modifican el indicador de acarreo, por lo que pueden usarse para realizar un bucle sobre operandos aritméticos de precisión arbitraria . [1] : 84, 101 DEC
CPC
, SBC
y SBCI
(comparar/restar con acarreo) no activan el indicador Z cuando el resultado es cero, sino que solo lo borran si el resultado no es cero. [1] : 79,147,149 Para comparaciones multibyte de precisión fija , implementadas con una secuencia desenrollada CP; CPC; CPC; CPC
, esto produce un indicador cero que se activa solo si la diferencia total es cero.Los siguientes espacios de direcciones están disponibles:
Los primeros 64 registros de E/S son accesibles a través del espacio de direcciones de E/S y de datos. Por lo tanto, tienen dos direcciones diferentes. Estas se escriben normalmente como " 0x00 ( 0x20 )" a " 0x3F ( 0x5F )", donde el primer elemento es la dirección de E/S y el segundo, entre paréntesis, la dirección de datos.
A excepción de los registros de la CPU para fines especiales, se puede acceder como registros de E/S. Es posible que algunos registros (RAMPX, RAMPY) no estén presentes en máquinas con menos de 64 KiB de memoria direccionable.
Un mapa de memoria ATmega típico podría verse así:
donde RAMEND es la última dirección de RAM. En las partes que carecen de E/S extendidas, la RAM comenzaría en 0x0060 .
Las operaciones aritméticas funcionan en los registros R0–R31 pero no directamente en la RAM y toman un ciclo de reloj, excepto la multiplicación y la suma de toda la palabra (ADIW y SBIW) que toman dos ciclos.
Solo se puede acceder a la memoria RAM y al espacio de E/S copiando hacia o desde los registros. El acceso indirecto (incluido el posincremento, predecremento o desplazamiento de constante opcionales) es posible a través de los registros X, Y y Z. Todos los accesos a la memoria RAM requieren dos ciclos de reloj. El movimiento entre registros y E/S requiere un ciclo. El movimiento de datos de ocho o dieciséis bits entre registros o de una constante a otro también requiere un ciclo. La lectura de la memoria de programa (LPM) requiere tres ciclos.
Las instrucciones son una palabra de 16 bits de longitud, excepto aquellas que incluyen una dirección de 16 o 22 bits, que ocupan dos palabras.
Existen dos tipos de bifurcaciones condicionales: saltos a direcciones y omisiones. Las bifurcaciones condicionales (BRxx) pueden probar un indicador de ALU y saltar a una dirección específica. Las omisiones (SBxx) prueban un bit arbitrario en un registro o E/S y omiten la siguiente instrucción si la prueba fue verdadera.
A continuación:
No todas las instrucciones están implementadas en todos los controladores AVR de Atmel . Este es el caso de las instrucciones que realizan multiplicaciones, cargas/saltos/llamadas extendidas, saltos largos y control de potencia.
Las instrucciones opcionales pueden agruparse en tres categorías:
Si bien los procesadores de gama alta tienden a tener núcleos más capaces y más memoria, la presencia de uno no garantiza la presencia del otro.
Partiendo del núcleo “clásico” original, las mejoras se organizan en los siguientes niveles, cada uno de los cuales incluye todos los anteriores:
LPM
instrucción, que es equivalente a LPM r0,Z
.MOVW
instrucción para mover pares de registros y la forma más general de la instrucción LPM ( LPM Rd,Z
y LPM Rd,Z+
) que permiten un registro de destino arbitrario y el incremento automático del puntero Z.XCH
: intercambio ( ), carga y configuración, carga y borrado y carga y alternancia. Estas instrucciones ayudan a coordinarse con los periféricos de acceso directo a la memoria , en particular un controlador USB .Hay dos subconjuntos de núcleos de CPU menos capaces que los "clásicos": el núcleo "AVR1" y el "AVR tiny". Resulta confuso que los procesadores de la marca "ATtiny" tengan una variedad de núcleos, incluidos AVR1 (ATtiny11, ATtiny28), classic (ATtiny22, ATtiny26), classic+ (ATtiny24) y AVRtiny (ATtiny20, ATtiny40).
El subconjunto AVR1 no fue popular y no se han introducido nuevos modelos desde el año 2000. Omite toda la RAM, excepto los 32 registros asignados en las direcciones 0 a 31 y los puertos de E/S en las direcciones 32 a 95. La pila se reemplaza por una pila de hardware de 3 niveles y se eliminan las instrucciones PUSH
y POP
. Se eliminan todas las operaciones de 16 bits, al igual que IJMP
, ICALL
y todos los modos de direccionamiento de carga y almacenamiento, excepto el indirecto a través de Z.
Un segundo intento, más exitoso, de subconjunto del conjunto de instrucciones AVR es el núcleo "AVR tiny".
El cambio más significativo es que el núcleo AVRtiny omite los registros R0–R15. Los registros tampoco están mapeados en memoria, con puertos de E/S de 0 a 63 y RAM de propósito general comenzando en la dirección 64. Se omiten las operaciones aritméticas de 16 bits ( ADIW
, ), al igual que la carga/almacenamiento con modos de direccionamiento de desplazamiento ( , ), pero se conservan los modos de direccionamiento de predecremento y postincremento. Se omite la instrucción; en su lugar, la ROM del programa se mapea al espacio de direcciones de datos y se puede acceder a ella con instrucciones de carga normales.SBIW
Y+d
Z+d
LPM
Por último, el núcleo AVRtiny elimina las instrucciones de 2 palabras LDS
y STS
para el direccionamiento directo de la RAM y, en su lugar, utiliza el espacio de código de operación previamente asignado a las instrucciones de carga/almacenamiento con desplazamiento para las nuevas instrucciones de 1 palabra LDS
y STS
que pueden acceder a las primeras 128 ubicaciones de la RAM de propósito general, direcciones 0x40 a 0xBF. (Las instrucciones IN
y OUT
proporcionan acceso directo al espacio de E/S de 0 a 0x3F).
Los núcleos más pequeños tienen ≤256 bytes de espacio de direcciones de datos (es decir, ≤128 bytes de RAM después de eliminar los puertos de E/S y otras direcciones reservadas) y ≤8192 bytes (8 KiB) de ROM de programa. Estos tienen solo un puntero de pila de 8 bits (en SPL) y solo admiten las instrucciones de salto/llamada relativas de 12 bits RJMP
/ RCALL
. (Debido a que el contador de programa AVR cuenta palabras de 16 bits, no bytes, un desplazamiento de 12 bits es suficiente para direccionar 2 13 bytes de ROM).
Existen capacidades de direccionamiento de memoria adicionales según sea necesario para acceder a los recursos disponibles:
JUMP
y . (Algunos modelos anteriores sufren una errata si una instrucción de omisión es seguida por una instrucción de 2 palabras).CALL
ELPM
instrucción y el registro RAMPZ correspondiente. LPM
Las instrucciones extienden a cero la dirección de ROM en Z; ELPM
las instrucciones anteponen el registro RAMPZ para los bits altos. Esto no es lo mismo que la LPM
instrucción más general; existen modelos "clásicos" con solo la forma de operando cero de ELPM
(ATmega103 y at43usb320). Cuando está disponible el incremento automático (la mayoría de los modelos), actualiza toda la dirección de 24 bits, incluida RAMPZ.EIJMP
y EICALL
que utilizan EIND:Z como dirección de destino. (Las instrucciones IJMP
y anteriores ICALL
utilizan Z extendida a cero).LDS
/ STS
. A diferencia del acceso a la ROM, no hay instrucciones "extendidas" diferenciadas; en su lugar, los registros RAMP se utilizan incondicionalmente.Las tres instrucciones están presentes solo en los modelos que tienen la instalación de hardware correspondiente.
SPM
para almacenar en ROM flash, está presente solo en procesadores con ROM flash (la mayoría de ellos)BREAK
para invocar el depurador en chip, se omite en algunos modelos pequeños sin soporte de depurador en chipDES
Para realizar rondas de Estándar de cifrado de datos , está presente en los modelos XMEGA con soporte de acelerador DESLas arquitecturas distintas de AVR1 se nombran según las convenciones avr-libc. [2]
Un conjunto de registros reducido está limitado a R16 a R31. [1]
Asignaciones de bits:
El AVR de Atmel utiliza muchos campos divididos, donde los bits no son contiguos en la palabra de instrucción. Las instrucciones de carga/almacenamiento con desplazamiento son el ejemplo más extremo, donde un desplazamiento de 6 bits se divide en tres partes.