¿Cómo usar el código de ARM Assembly en un proyecto de Android?
android-ndk native-code (3)
No tengo mucha experiencia con Assembly y ARM, pero pude escribir algunas rutinas y me gustaría ver cómo se ejecutan en un dispositivo Android equipado con ARM (Nexus S). ¿Cuál es el procedimiento para incluir un archivo de código de ensamblado en un proyecto de Android? ¿Puedo llamarlo solo desde un código nativo o desde Java también?
Creo que esto debería ser posible cuando se usa el NDK que le permite escribir el código C / C ++ empaquetado en .apk y luego ejecutarlo en la plataforma de Android.
Con esto, podrá usar la palabra clave __asm__
en su código C (como se menciona en las notas de la versión de la Revisión 5b).
Puede llamar al ensamblado desde Android utilizando Java Native Interface y Android NDK.
Cedric menciona el uso de la palabra clave asm , mientras que yo prefiero incluir el código fuente del ensamblaje. He publicado un tutorial para hacer esto en mi sitio: http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html
Puede descargar el código fuente de mi ejemplo y ver cómo funciona. Una vez que vea un ejemplo funcional, es fácil modificarlo según sus necesidades.
Ejemplo mínimo con archivo fuente en línea y separado
Se debe tener cuidado de no compilar el conjunto sin procesar bajo el arco equivocado. Aquí usamos:
-
#ifdef
s en archivos C -
ifeq
s enAndroid.mk
Este ejemplo en GitHub . Probado en Ubuntu 16.04, Android NDK 12, Sony Xperia Z3 D6643 (ARMv7) con Android 5.1.1.
jni / main.c
#include <stdio.h>
#include <jni.h>
#ifdef __arm__
int asm_main(void);
#endif
jstring Java_com_cirosantilli_android_1cheat_ndk_1asm_Main_jniMethod(
JNIEnv* env, jobject thiz) {
enum Constexpr { N = 256 };
char s[N];
size_t cur = 0;
int x = 0;
#ifdef __arm__
cur += snprintf(s + cur, N - cur, "arm ");
/* Inline test. Increment x by 1. */
asm (
"add %0, #1"
: "=r" (x)
: "0" (x)
);
/* Separate source test. Increment x by 1. */
x += asm_main();
#endif
if (x == 2)
cur += snprintf(s + cur, N - cur, "%s", "0");
else
cur += snprintf(s + cur, N - cur, "%s", "1");
return (*env)->NewStringUTF(env, s);
}
jni / main_asm.S
.text
/* Function that just returns 1. */
.global asm_main
asm_main:
mov r0, #1
bx lr
jni / Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.c
# http://.com/questions/12614417/android-ndk-how-to-get-compiler-architecture-in-android-mk-dynamically
ifneq (,$(filter $(TARGET_ARCH_ABI),armeabi armeabi-v7a))
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) main_asm.S
endif
include $(BUILD_SHARED_LIBRARY)
com / cirosantilli / android_cheat / ndk_asm / Main.java
package com.cirosantilli.android_cheat.ndk_asm;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText(jniMethod());
setContentView(tv);
}
public native String jniMethod();
static {
System.loadLibrary("main");
}
}