Cómo utilizar el lenguaje ensamblador en Android
Por mi parte, estoy usando las últimas herramientas de desarrollo de Android 4.0 y el NDK también es la última versión compatible con 4.0. Este NDK tiene algunas diferencias bastante significativas con respecto a versiones anteriores.
Ya que estoy usando Mac OS
Primero, establezca la ruta de destino: vaya al directorio raíz del NDK en la terminal, luego escriba NDK en la terminal, luego escriba NDK_PROJECT_PATH="
Presione Enter.
Cabe señalar aquí que la ruta después de NDK_PROJECT_PATH= debe citarse; de lo contrario, no será válida.
Dado que las opciones de compilación predeterminadas admitidas por el NDK solo admiten arquitecturas ARMv5 a ARMv5TE de forma predeterminada, si desea utilizar funciones más avanzadas, existen dos métodos:
1, tiene una manera de cambiar el valor de TARGET_ARCH_ABI a armeabi-v7a. Lo intenté yo mismo, pero no funcionó. Entonces puedes usar el segundo método, que es más simple y conveniente:
2. Encuentra cadenas de herramientas en tu directorio NDK, luego busca el directorio arm-linux-androideabi-x.y.z, donde puedes encontrar setup .mk. archivos. Busque -march=armv7-a, elimine todos los #ifdef incorrectos que se encuentran encima y elimine todos los #endif que se encuentran debajo. Esto asegurará que el compilador se compile con ARMv7A.
Después de completar el trabajo anterior, podemos comenzar a escribir ensamblador de la forma más sencilla, es decir, ensamblador en línea:
static int my_thumb(int dummy)
{
__asm__("movw r0, #1001 \t\n"
"movw r12, #2020 \t\n"
"añadir r0, r0, r12 \t\n"
"bx lr");
devolver ficticio;
}
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
my_thumb(0);
return (*env)-> ;NewStringUTF(env, "Hello from JNI!") ;
}
El código anterior en realidad se basa en el saludo- that viene con el proyecto NDK modificado por jni. Se compila correctamente utilizando ndk-build.
El código anterior se compila usando Thumb/Thumb-2 de forma predeterminada, por lo que las instrucciones que escribí en el ensamblado en línea son código Thumb.
A continuación analizaremos el uso del código ARM y el conjunto de instrucciones NEON.
Primero, cambie LOCAL_SRC_FILES en Android.mk y agregue el sufijo .neon después del nombre del archivo fuente; por ejemplo, cambie LOCAL_SRC_FILES := hello-jni.c a LOCAL_SRC_FILES := hello-jni.c.neon
Lo importante a tener en cuenta aquí es que el nombre real del archivo fuente no debe cambiarse, solo el valor del símbolo LOCAL_SRC_FILES.
Luego agregamos una nueva variable que indica a ARM GCC que compile usando el conjunto de instrucciones ARM: LOCAL_ARM_MODE := arm
Eso es todo. Modifiquemos el código:
static int my_arm(int dummy)
{
__asm__("movw r0, #1001\t\n"
"movw r12, #2020\t\n"
"añadir r0, r0, r12\t\n"
"vdup.32q0, r0 \t\ n"
"bx lr");
devolver ficticio;
}
jstring p>
Java_com_example_hellojni_ HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
my_arm(0);
return (*env)->NewStringUTF(env, "¡Hola desde JNI!");
}
Utilice ndk-build para compilar correctamente.
Por último, la gama más alta. ndk viene con herramientas GAS, por lo que normalmente es perfectamente posible escribir archivos ensambladores. En términos generales, los archivos ensamblados tienen una extensión .s, por lo que solo necesitamos crear un archivo xxx.s.
Luego, creo un archivo llamado hey.s y agrego este archivo en Android.mk: LOCAL_SRC_FILES += hey.s.neon
Podemos ver, para poder usar Para las instrucciones NEON establecidas en archivos ensambladores, también agregamos aquí el sufijo .neon. El archivo MAKE del ensamblador también reconoce este identificador.
Editamos el archivo hey.s:
.text
.align 4
.arm
. globl my_real_arm
my_real_arm:
agregar r0, r0, #256
vmov q0, q1
vdup.32q0, r0 < / p>
bx lr
Cabe señalar aquí que en el ensamblador de Apple, el nombre de la función tiene un guión bajo como prefijo, mientras que el ensamblador proporcionado por el NDK no requiere guiones bajos.
Modifiquemos hello-jni.c para llamar a esta función:
extern void my_real_arm(int i);
static int my_arm(int dummy)
{
__asm__("movw r0 , #1001 \t\n"
"movw r12, #2020 \t\n"
"añadir r0, r0, r12 \t\n"
"vdup.32q0, r0\t\n"
"bx lr");
devolver ficticio;
}
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz ) p>
{
mi_brazo_real(0);
mi_brazo(0);
return (*env)->NewStringUTF( env, "¡Hola desde JNI!");
}
Por supuesto, podemos forzar el uso del indicador -mthumb-interwork en el indicador TARGET_CFLAGS en setup.mk para garantizar que el compilador es capaz de ejecutar correctamente la concatenación mixta de conjuntos de instrucciones ARM y Thumb
Pruebe en el sistema operativo Windows. Finalmente, descubrí que podía usar neón con éxito eliminando armeabi del indicador APP_ABI en Application.mk y dejando solo armeabi-v7a. Esto no requiere modificar setup.mk ni eliminar el criterio de marca en Sample, lo cual es muy conveniente.
La siguiente es una lista de archivos de configuración de compilación de Android.mk disponibles:
LOCAL_PATH := $(call my-dir)
incluye $(CLEAR_VARS)
p>LOCAL_MODULE := HelloNeon
LOCAL_SRC_FILES := helloneon.c
LOCAL_ARM_MODE := brazo
TARGET_CFLAGS += -mthumb- intertrabajo
TARGET_CFLAGS += -std=gnu11
TARGET_CFLAGS += -std=gnu11
TARGET_CFLAGS += -O3
ifeq ($(TARGET_ARCH_ABI) ,armeabi-v7a )
LOCAL_CFLAGS := -DHAVE_NEON=1
LOCAL_SRC_FILES += neontest.s.neon
LOCAL_ARM_NEON := verdadero
endif
LOCAL_LDLIBS := -llog
incluye $(BUILD_SHARED_LIBRARY)
$(llamar al módulo de importación, cpufeatures)
Cuando utilice JNI, simplemente agregue la carpeta jni al directorio del proyecto actual y compílelo de acuerdo con el diseño de archivo proporcionado en el Ejemplo.
Cuando compila usando ndk-build (en Windows debe usar ndk-build.cmd en la consola cygwin), si la compilación es exitosa, se genera libXXX.so en la carpeta libs. Luego use Eclipse ADT para reabrir su proyecto. Encontrará que el directorio del archivo jni y el archivo so generado se ubicarán en el directorio de archivos de su proyecto. Por supuesto, también puede editar el archivo ensamblador .s directamente en el IDE de Eclipse más adelante, lo que será más conveniente de leer.
Finalmente, si desea comentar declaraciones en el ensamblador de Android, debe usar los caracteres de comentario en C89/90 - /* ...*/
Usar punto y coma y posteriores en El // formulario introducido en C++98 no funciona.
La última versión de NDK (android-ndk-r8d) contiene ARM-Linux GCC4.7 y el actualmente popular LLVM Clang3.1, pero dado que muchas opciones de compilación de LLVM Clang3.1 son diferentes de GCC, usted Debe configurar sus propias opciones de compilación para usar Clang3.1. La cadena de herramientas del compilador predeterminada para esta versión del NDK utiliza GCC 4.6. Si desea utilizar GCC4.7, puede agregar NDK_TOOLCHAIN_VERSION=4.7 en el archivo Application.mk; si desea utilizar Clang3.1, puede agregar NDK_TOOLCHAIN_VERSION=clang3.1 en el archivo Application.mk. El contenido del Application.mk legal es el siguiente:
# Construir usando LLVM Clang3.1
#NDK_TOOLCHAIN_VERSION=clang3.1
# Usar ARM- Linux GCC4.7 Build
NDK_TOOLCHAIN_VERSION=4.7
# Solo compila código de máquina ARMv7-A.
APP_ABI := armeabi-v7a