# data[].attributes.body
La arquitectura ARMv6 presenta un conjunto de 17 registros (16 principales más uno de estado) de 32 bits cada uno.

Registros Generales:
Tienen como función el almacenamiento temporal de datos.

# data[].attributes.body
Las instrucciones de multiplicación admiten muchas posibilidades, debido a que es una operación en la cual el resultado tiene el doble de bits que cada operando.

La instrucción mul realiza una multiplicación truncada, es decir, nos quedamos con los 32 bits inferiores del resultado. Como el signo del resultado es el bit más significativo el cual no obtenemos, esta multiplicación es válida tanto para operandos naturales (sin signo) como para enteros (con signo)

 mul r0, r1, r2

Las dos siguientes multiplicaciones (umull y smull) son largas, por eso la l del final, donde el resultado es de 64 bits. Si los operandos son naturales escogemos la multiplicación sin signo (unsigned) umull. Por el contrario, si tenemos dos enteros como factores hablamos de multiplicación con signo (signed) smull. En ambos ejemplos la parte baja del resultado se almacena en r0, y la parte alta en r1. Para hacer que r1:r0 = r2*r3:

umull r0, r1, r2, r3 smull r0, r1, r2, r3

# data[].attributes.body
Las instrucciones de desplazamiento pueden ser lógicas o aritméticas. Los desplazamientos lógicos desplazan los bit del registro fuente introduciendo ceros (uno o más de uno). El último bit que sale del registro fuente se almacena en el flag C. El desplazamiento aritmético hace lo mismo, pero manteniendo el signo.

Las instrucciones de rotación también desplazan, pero el bit que sale del valor se realimenta. No existe ninguna instrucción para rotar hacia la izquierda ROL, ya que puede simularse con la de rotación a la derecha ROR que sí existe. En estas instrucciones el bit desplazado fuera es el mismo que el que entra, además de dejar una copia en el flag C.

# data[].attributes.body
Cuando se representa cualquier dato en memoria, éste tiene un valor explícito (el que tiene como dato guardado en binario) y un valor implícito (el que tiene interpretado como un tipo de dato determinado o como una instrucción).

# data[].attributes.body
La traducción o ensamblado de un módulo fuente (nombreprograma.s) se realiza con el programa Gnu Assembler, con el siguiente comando:

as -o nombreprograma.o nombreprograma.s

Tanto el comando as como el nombre del programa son sensibles a las mayúsculas. El comando debe ir en minúsculas y el nombre como queramos. El as genera un fichero nombreprograma.o. Para montar (linkar) hay que hacer:

gcc -o nombreprograma nombreprograma.o

NOTA: Nuevamente, tanto gcc como el nombre del programa deben estar en minúsculas. Este comando es muy parecido al anterior,  la única diferencia es que el archivo no tiene extensión, que por otro lado es una práctica muy recomendable para ejecutables en Linux.

Una vez hecho esto, ya tenemos un fichero ejecutable (nombreprograma) que podemos ejecutar o depurar con el gdb.

# data[].attributes.body
ARM es una arquitectura de tipo RISC desarrollada por ARM Holdings pero fabricada por diversas compañías.

El chip que lleva la Raspberry Pi es el BCM2835, el cual es un sistema de un solo chip que contiene además de la CPU elementos como un núcleo GPU y un núcleo DSP (Procesamiento Digital de Señales) que es un procesador más pequeño y simple que el principal, pero especializado en el procesado y representación de señales analógicas.

# data[].attributes.body
Son expresiones que aparecen en el módulo fuente e indican al compilador que realice determinadas tareas, siempre comienzan con un punto. Es solo aplicable al entorno del compilador.

Directivas de asignación:
Se utilizan para dar valores a las constantes o reservar posiciones de memoria para las variables (.byte, .hword, .word, .ascii, .asciz, .zero y .space)
La directiva .equ (o .set) es utilizada para asignar un valor a una constante simbólica.

Directivas de Control:
.text y .data sirven para delimitar las secciones de nuestro módulo .align  es para alinear el siguiente dato rellenando con ceros, de tal forma que comience en una dirección múltiplos del número que especifiquemos.
.include para incluir un archivo fuente dentro del actual, .global hace visible al enlazador el símbolo que hemos definido con la etiqueta homónima.

Directivas de Operando.
Se aplican a los datos en tiempo de compilación. En general, incluyen las operaciones lógicas &, |, ∼, aritméticas +, -, *, /, % y de desplazamiento <, >, <<, >>:

Directivas de Macros:
Una .macro es un conjunto de sentencias en ensamblador (directivas e instrucciones) que pueden aparecer varias veces repetidas en un programa con algunas modificaciones (opcionales) .

# data[].attributes.body
Instrucciones de transferencia de datos:
Mueven información entre registros y posiciones de memoria (mov, ldr, str, ldm, stm, push, pop).

Instrucciones aritméticas:
Realizan operaciones aritméticas sobre números binarios o BCD (add, cmp, adc, sbc, mul).

Instrucciones de manejo de bits:
Realizan operaciones de desplazamiento, rotación y lógicas sobre registros o posiciones de memoria (and, tst, eor, orr, LSL, LSR, ASR, ROR, RRX).

Instrucciones de transferencia de control.
Se utilizan para controlar el flujo de ejecución de las instrucciones del programa como (b, bl, bx, blx y sus variantes condicionales).

# data[].attributes.body
Registros Especiales:
Son los últimos 3 registros principales: R13, R14 y R15.

SP/R13: Puntero de Pila
Sirve para almacenar variables locales y registros en llamadas a funciones.

LR/R14: Registro de Enlace
Almacena la dirección de retorno de una instrucción BL o BLX ejecuta una llamada a una rutina.

PC/R15: Contador de Programa
Registro que indica la posición del procesador en su secuencia de instrucciones.

# data[].attributes.body
Formato general de As:

Etiqueta: Nemotécnico Operando/s  /*Comentario */

De estos campos solo el nemónico (la instrucción) es obligatorio.

main : ldr    r1, puntero_var1 /* r1 <- & var1 */

El campo etiqueta, si aparece debe estar formado por una cadena alfanumérica, no debe comenzar con un dígito y no se puede utilizar como cadena alguna palabra reservada del as ni nombre de registro del microprocesador.

El campo Nemotécnico es una forma abreviada de nombrar la instrucción del procesador, esta formado por caracteres alfabéticos.

El campo Operando/s indica donde se encuentran los datos, puede haber 0,1 o más operando en una instrucción.
Si hay más de uno normalmente al primero se le denomina destino y a los demás fuentes

El campo Comentario es opcional y debe comenzar y terminar con /* ,*/ al igual que los comentarios multilínea en C.

# data[].attributes.body
Sección de Datos:

Identificada por .data

Se definen las variables

Datos alineados en 4 bytes

Datos modificables

Sección de Código:

Identificada por .text

Solo pueden contener código

Datos no modificables

Instrucciones de 32 bits

La única que debe existir obligatoriamente es la sección de código

# data[].attributes.body
Para representar números tenemos 4 bases:

1. Decimal: No lleva ningún delimitador especial.
2. Hexadecimal: Prefijo 0x
3. Binario: Prefijo 0b
4. Octal: Prefijo 0

Para representar caracteres y cadena emplearemos las comillas simples y comillas dobles respectivamente.

# data[].attributes.body
Sintácticos o Detectables en Tiempo de Traducción:

Estos son escribir mal una instrucción o hacer una operación entre dos datos incompatibles, son detectados por el traductor y se deben solucionar para poder generar un ejecutable.

Semánticos o Detectables en Tiempo de Ejecución:

Todas las instrucciones pueden ser correctas pero se puede haber olvidado poner la condición de salida de un bucle o el programa no hace lo que queremos, para poder eliminarnos se utiliza un debugger.

# data[].attributes.body
En la zona de datos las etiquetas pueden representar variables, constantes y cadenas. En la zona de código podemos usar etiquetas de salto, funciones y punteros a zona de datos.

La macros y las constantes simbólicas son símbolos cuyo ámbito pertenece al preprocesador, a diferencia de las etiquetas que pertenecen al del ensamblador.  Se especifican con .macro y .equ respectivamente y permiten que el código sea más legible y menos repetitivo.

# data[].attributes.body
La dirección de un dato es la de su byte menos significativo. La memoria siempre se referencia a nivel de byte.

# data[].attributes.body
Escribir el programa en lenguaje fuente

Utilizar un programa traductor

Generar un fichero traducido

Unir el código del programa con las librerías a través del linker que genera el ejecutable

(Un fichero ejecutable contiene el programa traducido mas una serie de códigos en los cuales se encuentran las librerías de lenguaje).

# data[].attributes.body
Almacena banderas condicionales y bits de control, los cuales definen la habilitación de interrupciones normales, rápidas; modo Thumb y el modo de operación de la CPU.

Existen hasta 8 modos de operación pero solo se trabaja el Modo Usuario ya que los demás son modos privilegiados del SO.

Desde este modo podemos acceder a las banderas condicionales que contienen información sobre la última operación realizada por la ALU.

N: Se activa cuando el resultado es negativo.

Z: Se activa cuando el resultado es cero o una comparación es cierta

C: Indica acarreo de las operaciones aritméticas.

V: Desbordamiento aritmético.

# data[].attributes.body
Lenguaje de bajo nivel

Permite control directo del CPU y elementos asociados.

Cada línea consta de una instrucción del procesador y la posición que ocupan los datos.

Conjunto de instrucciones forman módulo fuente que será la entrada del compilador, donde se chequea la sintaxis y se traduce a código máquina formando un modulo objeto.  Finalmente un enlazador traduce las referencias relativas a direcciones absolutas y termina generando el ejecutable.

Se utiliza como apoyo a lenguajes de alto nivel para:

Operaciones que se repitan multiples veces

Gran velocidad de proceso

Utilización y aprovechamiento de dispositivos y recursos del sistema