Nuestro
objetivo es ejecutar un programa escrito en lenguaje ensamblador
(x86 o ARM) en un dispositivo que tenga esa arquitectura.
El
primer paso a la hora de realizar esta tarea es tomar unas cuantas
decisiones, siendo la primera de ellas la arquitectura con la que
vamos a trabajar. En este artículo trabajaremos con la
arquitectura ARM.
La
arquitectura ARM es empleada hoy día por multitud de dispositivos:
móviles, tablets, sistemas empotrados, microcontroladores, etc. El
dispositivo que vamos a utilizar es nuestro smartphone, por dos
motivos:
- Disponibilidad: en la actualidad, casi todo el mundo tiene un smartphone a su alcance
- Documentación: la programación para dispositivos móviles está en su punto álgido de popularidad, por lo que la cantidad de documentación e información que nos facilita trabajar con smartphones es considerablemente mayor que con otros dispositivos o plataformas.
Lo
primero que deberíamos hacer es comprobar que nuestro smartphone
utiliza una arquitectura ARM. Ésto lo podemos consultar en la
documentación de nuestro smartphone o buscando sus especificaciones
técnicas en internet. En mi caso, voy a utilizar un Huawei Ascend
Y300, que utiliza un procesador Qualcomm MSM8225. Wikipedia nos
confirma que, efectivamente....
...éste
procesador trabaja con arquitectura ARM, más concretamente el juego
de instrucciones ARMv7. Comprobado esto, vamos a preparar nuestro
smartphone (y nuestro ordenador) para poder testear nuestros
programas en él.
En
este artículo vamos a trabajar con un móvil equipado con el sistema
operativo Android. Sin embargo, no vamos a trabajar sobre Android,
sino sobre una distribución de Linux (Debian
en mi caso). ¿Por qué?
La
programación en Android se centra, sobre todo, en el desarrollo de
aplicaciones, es decir, la programación en alto nivel, sobre todo en
lenguaje JAVA, utilizando la plataforma de desarrollo de Android
(SDK). Existe una “expansión” de esta plataforma, el NDK o
“Native Development Kit” (kit de desarrollo nativo), para
implementar a nuestras aplicaciones código en lenguaje de más bajo
nivel que JAVA, como pueden ser C, C++, o incluso lenguajes
ensamblador como ARM, MIPS o x86. Para ejecutar nuestro código
ensamblador, necesitamos apoyarnos en código C y JAVA.
En
conclusión, trabajar sobre Android es considerablemente más
engorroso que trabajar sobre Linux, donde podemos compilar y
ejecutar nuestro código en ensamblador introduciendo una sóla línea
en el terminal. Aprovechando que existe un port de la
distribución Debian de Linux para el set de instrucciones ARMv7, es
más cómodo instalar Debian en nuestro smartphone y trabajar
directamente sobre él.
Existen
diversas maneras de montar en nuestra tarjeta SD una imagen de la
distribución de Linux que elijamos.
Yo personalmente me decanté por la aplicación Debian Kit, que
provee facilidad de instalación y uso, una guía de instalación y
uso muy detallada, y además trabaja paralelamente con Android. Es
importante aclarar que esta aplicación requiere acceder a nuestro
smartphone como superusuario o “root”: debemos
hacer lo que se conoce popularmente como “rootear” nuestro
teléfono,
tarea que hoy día es completamente trivial y no requiere,
dependiendo del sistema que utilicemos, más de 5 minutos y un par de
clicks. Yo utilicé la aplicación Kingo (http://www.kingoapp.com/).
Una
vez rooteado el terminal, podemos montar nuestra imagen de Debian en
él. Existen
multiples maneras de implementar un sistema operativo Linux funcional
en nuestro smartphone.
Yo elegí Debian Kit, junto con la aplicación ConnectBot para hacer
de shell local, por los motivos antes mencionados. El creador de esta
aplicación detalla estupendamente el proceso de instalación y de
uso de esta aplicación aquí:
http://sven-ola.dyndns.org/repo/debian-kit-en.html.
Recordad que debemos disponer de al menos medio gigabyte de espacio
libre en la tarjeta MicroSD de nuestro móvil.
ConnectBot
es el cliente SecureShell para Android más utilizado y valorado. Un
cliente SSH (Secure Shell o “intérprete de ordenes seguro) es,
citando a la Wikipedia, “el nombre de un protocolo y del programa
que lo implementa, y sirve para acceder a máquinas remotas a través
de una red”. En nuestro caso, y si hemos seguido el tutorial,
estaremos utilizando una shell local; es decir, utilizaremos
ConnectBot para comunicarnos, mendiante línea de comandos, con el
sistema Debian que acabamos de instalar.
Ya
disponemos de Debian en nuestro móvil. Es posible, llegados a este
punto, crear una shell remota ssh para poder manejar nuestro móvil
sin tener que lidiar con el incómodo teclado táctil del móvil,
usando android bridge (adb) y ssh (secure shell); no obstante, no es
realmente necesario (aunque sí bastante práctico)
El
siguiente paso es instalar un compilador/ensamblador. Yo he
optado por el compilador de propósito múltiple, GNU GCC, puesto que
es el más ampliamente usado y el estándar. La orden "apt-get install gcc" instala el compilador.
Llegados
a este punto, ya podríamos ensamblar y ejecutar un archivo .s de
código en ensamblador ARM. Con la instrucción:
gcc
-o prueba codigo.s && ./prueba
Generaríamos
un archivo objeto “prueba” a partir de nuestro archivo de código
ensamblador “codigo.s”, y lo ejecutaríamos
Vamos
a usar el ensamblador GNU. GNU es un ensamblador que soporta
múltiples arquitecturas; por lo tanto, la sintaxis es distinta a la
del ensamblador armasm de ARM, y debemos adaptar nuestro programa a
dicha sintaxis.
- Los comentarios son precedidos por el símbolo '@' o '#', no ';'
- Las etiquetas deben terminar con el símbolo ':'
- Las directivas son diferentes.
A continuación muestro el programa que he ejecutado: un simple Hola Mundo
Aquí vemos varias notables diferencias con lo visto en prácticas. La primera y mas obvia son las directivas y su sintaxis; aunque, como vemos, las instrucciones apenas varían.
Digo apenas porque hay un par de pequeñas variaciones. En las prácticas empleabamos ADR para asignar una etiqueta a un registro, mientras que aquí usamos LDR, y ponemos un signo = antes de la etiqueta. También usábamos SWI para las llamadas al sistema; SWC ya está obsoleto, siendo ahora el estándar SVC o "supervisor call".
La segunda son las llamadas al sistema. Cada sistema operativo tiene su propia convención de llamadas al sistema. En el caso de Linux, cargamos en r7 el código de la llamada al sistema; en nuestro caso la llamada 4, asignada a la función write(). Los argumentos que le pasamos a la función se almacenan en r0, r1, r2 y r3. En r0 establecemos el "file descriptor": 0 para entrada estandar, 1 para salida estandar, y 2 para salida de errores estandar. En r1 establecemos la cadena a imprimir, y en r2, su longitud en bytes (como bien sabemos, 1 caracter = 1 byte). Aquí vemos cómo ensamblar y ejecutar, con una simple línea, nuestro código: (la opción nostdlib evita que se enlace nuestro programa con librerías estandar; por algún motivo, esa fase de enlace me estaba provocando errores, por eso la deshabilité. También es posible usar -c con un fin parecido).
Por Santiago Zaldívar Lavalle
Casinos & Slot Machines | DrMCD
ResponderEliminarWith the success of online slots, you 밀양 출장샵 will 이천 출장마사지 enjoy an immersive The first casino and gaming 양산 출장안마 destination in 강원도 출장샵 the Netherlands, Rating: 4.3 · 9 성남 출장안마 reviews