19
UNIVERSIDAD AUTÓNOMA DE TAMAULIPAS - FACULTAD DE MEDICINA E INGENIERÍA EN SISTEMAS COMPUTACIONALES DE MATAMOROS Manual de laboratorio para la materia Lenguaje Ensamblador basado en la arquitectura ARM Raspberry Pi + Lenguaje Ensamblador I.S.C. Oscar Alejandro Paz Balderas, M.S.C. 21/01/2013 Un enfoque práctico y actualizado de algunos ejercicios de laboratorio, para la materia de lenguaje ensamblador tomando como base la arquitectura ARM, y objeto de trabajo la computadora de bajo costo Raspberry Pi.

Manual Lenguaje Ensamblador Rpi Enero 2013

Embed Size (px)

DESCRIPTION

Un enfoque práctico y actualizado de algunos ejercicios de laboratorio, para la materia de lenguaje ensamblador tomando como base la arquitectura ARM, y objeto de trabajo la computadora de bajo costo Raspberry Pi.

Citation preview

  • UNIVERSIDAD AUTNOMA DE TAMAULIPAS - FACULTAD DE MEDICINA E INGENIERA EN SISTEMAS COMPUTACIONALES DE MATAMOROS

    Manual de laboratorio para la materia Lenguaje

    Ensamblador basado en la arquitectura ARM

    Raspberry Pi + Lenguaje Ensamblador

    I.S.C. Oscar Alejandro Paz Balderas, M.S.C.

    21/01/2013

    Un enfoque prctico y actualizado de algunos ejercicios de laboratorio, para la materia de lenguaje ensamblador tomando como base la arquitectura ARM, y objeto de trabajo la computadora de bajo costo Raspberry Pi.

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 1 -

    ndice:

    Introduccin: ............................................................................................................................................. - 1 -

    Ejercicio #1: ............................................................................................................................................... - 1 -

    Ejercicio #2: ............................................................................................................................................... - 2 -

    Ejercicio #3: ............................................................................................................................................... - 3 -

    Ejercicio #4: ............................................................................................................................................... - 7 -

    Ejercicio #5: ............................................................................................................................................. - 11 -

    Ejercicio #6: ............................................................................................................................................. - 12 -

    Ejercicio #7: ............................................................................................................................................. - 14 -

    Ejercicio #8: ............................................................................................................................................. - 15 -

    Ejercicio #9: ............................................................................................................................................. - 17 -

    Ejercicio #10: ........................................................................................................................................... - 17 -

    Material de Apoyo: ................................................................................................................................. - 18 -

    Introduccin: El presente manual est enfocado hacia la arquitectura ARM de 32 bits, y como ejemplo prctico se

    toma a la computadora de bajo costo Raspberry Pi.

    Para poder ejecutar los programas del presente manual se utiliza el ensamblador GNU.

    Ejercicio #1: Teora: En lenguaje ensamblador los comentarios son identificados de la siguiente manera: /*.*/; y son

    utilizados para aadir algunas notas o apuntes que puedan ser tiles para ti mismo o para algn otro

    programador.

    Existe otro concepto importante, que son las directivas; estas comienzan con un punto . y le dicen al

    ensamblador GNU que realice una actividad especial.

    Por ltimo se menciona el concepto de funcin, la cual recibe datos como parmetros de entrada y en

    algunas ocasiones emite datos.

    Objetivo: Hacer un programa que arroje el error #2 al ser ejecutado.

    Practica: Seguir los siguientes pasos para la elaboracin de este primer ejemplo.

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 2 -

    a) Crear un archivo llamado first.s, con el comando sudo nano first.s:

    b) Escribir los siguiente dentro del archivo:

    c) Para compilarlo se escribe:

    d) Esto crea el archivo objeto, llamado first.o. Ahora se debe de enlazar dicho archivo:

    e) Ya una vez que se cre el archivo ejecutable llamado first; se puede ejecutar de la siguiente

    manera:

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #2: Teora: La instruccin add aade los valores contenidos en 2 registros; estos valores deben de ser

    almacenados en un tercer registro.

    Objetivo: Crear un programa que aade 2 nmeros y desplegar el resultado.

    Practica: Crea un programa siguiendo estos pasos:

    a) Escribe en el LXTerminal la siguiente instruccin: sudo nano sum01.s.

    b) En el editor de texto escribe el siguiente programa:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 3 -

    c) Compila y ejecuta el programa. El resultado se debe de mostrar:

    d) Intenta otros valores en los registros r1 y r2; vuelve a compilar y ejecutar el programa.

    e) Ahora intenta de una mejor manera la adicin; utilizando de una forma ms inteligente el

    registro r0. Crea un nuevo programa llamado sum02, complalo, ejectalo y ve el resultado.

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #3: Teora: Todas las computadoras tienen memoria, y es ah donde el cdigo de un programa y los datos

    que este puede manejar son almacenados. El lugar donde se almacena la informacin dentro de la

    memoria se le llama registro.

    En la arquitectura ARM, todos los operandos deben de estar almacenados en registros; es por eso que

    se deben de cargar (load) dichos valores a algunos registros, para poder ser manipulados, se realiza la

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 4 -

    operacin aritmtica, y despus el resultado debe de ser almacenado (store) nuevamente a otro

    registro.

    Direccin: Para tener acceso a los datos, primero, necesitamos darles un nombre que es una direccin.

    La direccin es un nmero, en la arquitectura ARM un nmero de 32 bits identifica cada byte de

    memoria:

    Cuando se carga o almacenan datos desde o hacia la memoria, se

    necesita computar una direccin. Esta direccin puede ser computada en

    muchas maneras. Cada una de estas maneras es llamada modo de

    direccionamiento. ARM tiene varios modos de direccionamiento. En este ejemplo solo se considerar el

    direccionamiento a travs de un registro.

    Etiquetas: en lenguaje ensamblador, son nombres simblicos a direcciones dentro de un programa. Una

    etiqueta solamente describe una direccin, nunca su contenido.

    Datos: Las direcciones, pueden hacer referencia ya sea a datos o cdigo. As que nosotros podemos

    definir algunos datos y unir alguna etiqueta a su direccin. Es obligacin del programador de lenguaje

    ensamblador, asegurar que el dato almacenado este referenciado por una etiqueta con su valor y

    tamao apropiado. Por ejemplo, defina una variable de 4 bytes e inicialice esta variable a un valor de 3,

    entonces, se debe de escribir el siguiente cdigo:

    La directiva .balign asegura que la siguiente direccin empezara con un espacio de 4 bytes. La directiva

    .word declara que la herramienta del ensamblador debe emitir el valor del argumento de las directivas

    como un entero de 4 bytes. En el caso anterior, se emitir, un espacio de memoria de 4 bytes que tiene

    el valor 3.

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 5 -

    Secciones: Los datos son almacenados en la memoria al mismo tiempo que el cdigo del programa. Para

    definir el espacio donde se debe de almacenar los datos, se utiliza la directiva .data. En el caso del

    cdigo se utiliza la directiva .text.

    Objetivo: Calcule la suma de 2 nmeros. Los operandos deben de ser definidos en la seccin .data del

    programa. Una vez definidos, cargue los valores en los registros r1 y r2 respectivamente. Realice la

    operacin aritmtica. Despliegue el resultado.

    Practica: Realice los siguientes pasos:

    a) Escriba el siguiente cdigo en un programa llamado load01.s.

    b) Compila el programa y ejectalo:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 6 -

    c) Escriba otro programa llamado store01.s. Inicializa myvar1 y myvar2 a 0; almacena los valores 3

    y 4 a los registros. Compila y ejecuta el programa:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 7 -

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #4: Teora: GDB es un programa de depuracin en GNU. Este programa permite ver que est sucediendo

    adentro de un programa que est en ejecucin, o bien que est haciendo un programa al mismo tiempo

    que este colapsa. Se pueden hacer 4 tareas principales, que ayudan a buscar los errores dentro de los

    programas al mismo tiempo que se ejecuta:

    Empezar un programa, especificando los valores que pudieran afectar el comportamiento del

    programa bajo prueba.

    Hacer que el programa bajo prueba se detenga en un punto especfico.

    Examinar que pasa, cuando el programa bajo prueba se ha detenido.

    Cambiar algunos valores o cdigo en el programa, de tal manera que se pueda experimentar con

    las correcciones de algn error de cdigo y as facilitar la manera de encontrar errores.

    Objetivo: Utilice el programa titulado store01.s, para practicar con algunos comandos del depurador de

    errores GDB.

    Practica: Realice los siguientes pasos:

    a) Inicialice gdb, especificando el programa que se quiere analizar:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 8 -

    b) Para salirse de gdb, ejecute el siguiente comando:

    c) Para arrancar el depurador gdb nuevamente, ejecute start:

    d) Desensamble el programa, utilizando el comando disassemble:

    e) Para inspeccionar algunos registros, ejecute el siguiente comando:

    f) Se pueden modificar los valores de algunos registros, asignndoles valores en especfico; utilice

    el comando p:

    g) Se puede observar que gdb, ha impreso $1, este es un identificador del resultado, se puede

    utilizar cuando se requiera, as de esta manera se optimiza el proceso de ingreso de

    instrucciones.

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 9 -

    h) Ejecute la primera instruccin:

    i) Escriba el comando disassemble:

    j) Ahora, vamos a ver que paso en el registro r1:

    k) Como se pudo observar en la instruccin anterior, r1 ha cambiado. De hecho r1 contiene la

    direccin de myvar1. Compruebe esto, utilizando su valor simblico en la sintaxis de C.

    l) Como se pudo observar, ah estaba contenido una direccin de memoria. Ahora bien, para

    poder ver el valor que contena dicha direccin, ejecute el siguiente comando:

    m) Se pudo observar el valor 0, ya que ese valor fue como se inicializo myvar1 y myvar2. Contine

    con el siguiente paso. Observa que se puede utilizar disas en lugar de disassemble:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 10 -

    n) Ahora, observa que pasa con r3:

    o) Avanza una instruccin ms:

    p) Ahora, se puede ver que, lo almacenado en r3, esta tambin almacenado en myvar1. Sera

    cierto?

    q) Ejecute el programa hasta el final.

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 11 -

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #5: Teora: un registro especial en la arquitectura ARM es el registro r15, el cual se conoce como PC, y es el

    equivalente al registro IP-Instruction Pointer en otras arquitecturas. El registro PC o program counter,

    contiene la direccin de la siguiente instruccin a ser ejecutada. Cuando, el procesador ARM ejecuta una

    instruccin 2 cosas pueden pasar al final de la ejecucin: si la instruccin no modifica a PC (y la mayora

    de las instrucciones no lo hacen), PC se incrementa en un valor de 4. Por qu se incrementa un valor de

    4?, la respuesta es que en la arquitectura ARM, las instrucciones son 32 bits de ancho, as que hay 4

    bytes entre cada instruccin.

    Una vez que el procesador ha ejecutado completamente una instruccin, despus este utiliza el valor en

    el registro PC como la direccin para la siguiente instruccin a ser ejecutada. De esta forma una

    instruccin que no modifica a PC, ser seguida por la siguiente instruccin en la memoria (ya que ha sido

    incrementado de manera automtica por 4). Esto es llamado secuencia implcita de instrucciones:

    despus de que una instruccin es ejecutada, usualmente la siguiente en memoria lo hace. Pero si una

    instruccin modifica a PC, por ende debe de ser un valor diferente a PC + 4; entonces se debe de

    ejecutar otra instruccin del programa. Este proceso de cambiar los valores de PC es llamado

    Branching.

    Objetivo: Realizar un programa donde se practique el concepto de Branching.

    Practica: Crear un programa titulado compare01.s. Copia el siguiente cdigo:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 12 -

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #6: Teora: En este ejercicio, se utilizaran conceptos como estructuras if-then-else y ciclos (while y for).

    Objetivos:

    1. Crear un programa que sume los nmeros del 1 al 22.

    2. Crear un programa que resuelva la conjetura de Collatz (Dado un numero n, se dividir entre 2 si

    es par; si el nmero es impar, se multiplica por 1 y se suma 1).

    Practica:

    Objetivo 1:

    a) Escriba el siguiente cdigo en un programa llamado loop01.s.

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 13 -

    b) Conteste la siguientes preguntas:

    1. En qu registro se acumulan las sumas?

    2. En la lnea 8 se compara r2, Cul es el registro que se ve afectado en dicha

    comparacin?

    3. Podra modificar el programa, de tal manera que en lugar de contar hasta 22, cuente

    hasta 100?

    4. Existe algn manera de mejorar el ciclo del ejemplo loop01.s?, si es as, escriba un

    nuevo programa titulado loop02.s.

    Objetivo 2:

    a) Escriba el siguiente cdigo en un programa llamado collatz.s:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 14 -

    b) Conteste las siguientes preguntas:

    1. Cul es el nombre del registro donde se almacena el nmero n?

    2. Cul es el significado de ASR?

    3. Qu efectos tiene ASR en un registro?

    4. Cul es el significado de LSL?

    5. Qu efectos tiene LSL en un registro?

    6. Qu muestra el programa al ejecutar la instruccin ./collatz; echo $??

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #7: Teora: Para la realizacin de este ejercicio, se deben de haber revisado los conceptos de indexing.

    Adems de las operaciones de cambio (shift operations), como: LSL, LSR, ASR, ROR.

    Objetivo: Practicar algunas operaciones matemticas de multiplicacin y divisin, utilizando operaciones

    de cambio (shift operations).

    Practica: Escriba instrucciones en lenguaje ensamblador que realicen las siguiente operaciones:

    a) R1 (r2*2)

    b) R1(r2*4)

    c) R1(r3/8)

    d) R1(r2*16)

    e) R1r1*3

    f) R1r1*5

    g) R1r2*(-7)

    h) R1r2*7

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 15 -

    i) R17*r1

    j) R13*r1

    k) R12*r1

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #8: Teora: Hasta este momento los ejercicios se han enfocado hacia el segundo operando de la mayora de

    las instrucciones aritmticas. Para este segundo operando se pueden utilizar operaciones de cambio,

    que permiten mover hacia a izquierda o hacia la derecha, o bien rotar los bits de algn registro.

    Un arreglo: Es una secuencia de artculos del mismo tipo en la memoria. Los arreglos son fundamentales

    en casi cualquier lenguaje ensamblador. Cada arreglo tiene una direccin base, usualmente denotada

    por el nombre del arreglo, y contiene N artculos. Cada uno de estos artculos o tems tiene asociado un

    ndice que es creciente, que va desde 0 hasta N-1 o en algunos casos desde 1 hasta N. Utilizando la

    direccin base y el ndice se puede llegar a tener acceso a cada tem del arreglo.

    Una estructura (o registro, o tupla) es una secuencia de tems de diferente tipo. Cada tem de una

    estructura es usualmente llamado campo. Los campos no tienen ndices asociados, pero si tienen un

    offset con respecto al comienzo o inicio de la estructura. Las estructuras son ubicadas de manera

    horizontal en la memoria para asegurar que una alineacin apropiada es utilizada en cada campo. La

    direccin base de una estructura es la direccin de su primer campo. Si la direccin base est alineada,

    las estructuras deben de estar horizontalmente de tal manera que todos los campos estn alineados de

    manera apropiada.

    Objetivo: Practicar algunos conceptos de como accesar a una estructura, un arreglo utilizando lenguaje

    ensamblador. As como algunos modos de indexado.

    Practica: Realice las siguientes tareas:

    a) Crea un pequeo programa en lenguaje ensamblador que haga la misma tarea del siguiente

    cdigo:

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 16 -

    b) Escriba un cdigo en lenguaje ensamblador que inicialice los tems de un registro, tome el

    siguiente cdigo como ejemplo:

    c) Escriba un cdigo que represente los modos de indexado sin actualizacin:

    1. [Rsource1, +#immediate] o [Rsource1, -#immediate]

    2. [Rsource1, +Rsource2] o [Rsource1, -Rsource2]

    3. [Rsource1, +Rsource2, shift_operation #immediate] o [Rsource1, -Rsource2,

    shift_operation #immediate]

    d) Escriba un cdigo que represente los modos de indexado con actualizacin.

    e) Escriba un cdigo que represente los modos de post-indexado:

    1. [Rsource1], #+immediate o [Rsource1], #-immediate

    2. [Rsource1], +Rsource2 o [Rsource1], -Rsource2

    3. [Rsource1], +Rsource2, shift_operation #immediate o [Rsource1], -Rsource2,

    shift_operation #immediate

    f) Escriba un cdigo que represente los modos de pre-indexado:

    1. [Rsource1, #+immediate]! o [Rsource1, #-immediate]!

    2. [Rsource1, +Rsource2]! o [Rsource1, +Rsource2]!

    3. [Rsource1, +Rsource2, shift_operation #immediate] o [Rsource1, -Rsource2,

    shift_operation # immediate]

    g) Escriba un cdigo que incremente en 7 el valor del campo f1 de una estructura decladara como

    b.

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 17 -

    Ejercicio #9: Teora: En este ejercicio, se utilizan conceptos relacionados a la estructuracin estndar de

    procedimientos para la arquitectura ARM, AAPCS (Procedure Call Standard for the ARM Arquitecture). El

    escribir cdigo que se adhiere a AAPCS, se puede asegurar que los mdulos compilados y ensamblados

    de manera separada pueden trabajar juntos.

    Llamada a una funcin: existen 2 maneras de llamar una funcin:

    Llamada directa de la funcin: Si la funcin es conocida, se utiliza bl label; Esa etiqueta debe ser

    una etiqueta definida en la seccin .text.

    Llamadas indirectas de la funcin: se almacena la direccin de la funcin en un registro y

    despus se utiliza blx Rsource1.

    Objetivo: Practicar con alguna serie de ejercicios la declaracin, llamada y retorno a funciones.

    Practica: Realice los siguientes ejercicios:

    a) Escriba un programa titulado, que muestre el mensaje Hola Mundo!.

    b) Escriba un programa que utilice las funciones printf y scanf para leer un nmero y despus

    mostrar este mismo nmero en pantalla.

    c) Escriba un programa, que le un nmero y despus lo multiplica por 5, despus de debe de

    mostrar el resultado en pantalla. Se debe de declarar una funcin que haga la tarea de

    multiplicacin.

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Ejercicio #10: Teora: En computacin, la pila es una estructura de datos (una manera de organizar datos que proveen

    algunas propiedades interesantes). Una pila tpicamente tiene 3 operaciones: acceso a la parte ms alta

    de la pila, empujar hacia la pila (push) y remover de la pila (pop). La pila es una regin de memoria que

    tiene una estrecha relacin con una funcin, en otras palabras, la pila es una regin de memoria que

    tiene una relacin muy fuerte con la activacin dinmica actual. La pregunta ahora ser, y cmo se

    controla la pila?, el registro sp (stack pointer), siempre tiene el contenido de la parte alta de la pila. La

    regin de memoria apropiada por la activacin dinmica es la extensin de bytes contenidos entre el

    valor actual del apuntador de pila y el valor inicial que el apuntador de pila tuvo al principio de la

    funcin. A esta regin de memoria se le llama, memoria local de una funcin (ms precisamente, de una

  • Manual de Lenguaje Ensamblador para Raspberry Pi

    - 18 -

    activacin dinmica de esta). En ese espacio, se pondr lo que sea necesario almacenar al comienzo de

    la funcin y restablecido antes de dejarla, ah tambin se mantienen las variables locales de la funcin.

    Objetivo: Practicar el concepto de pila, al hacer el llamado recursivo de una funcin.

    Practica: Realice la siguiente actividad.

    a) Escriba un ejemplo que calcule el factorial de un nmero, llame este ejemplo como:

    factorial.s;

    Conclusiones: En el siguiente espacio, debes de escribir tus experiencias al elaborar este ejercicio.

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    _____________________________________________________________________________________

    ______________________________________________________________________________

    Material de Apoyo:

    ARM Developer Suite Assembler Guide [Fecha de consulta: Enero 2013]

    http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/CIHCJFJG.html

    ARM assembler in Raspberry Pi Chapter 1 [Fecha de consulta: Enero 2013]

    http://thinkingeek.com/2013/01/09/arm-assembler-raspberry-pi-chapter-1/

    GDB: The GNU Project Debugger [Fecha de consulta: Enero 2013]

    http://www.sourceware.org/gdb/

    The ARM instruction set [Fecha de consulta: Enero 2013]

    http://simplemachines.it/doc/arm_inst.pdf