How to use ARM Assembly code in an Android project?
I'm not particularly experienced with Assembly and ARM, but I was able to write a few routines in it and I'd like to see how they run on an ARM-equi开发者_如何转开发pped Android device (Nexus S). What is the procedure for including an Assembly code file into an Android project? Can I only call it from native code, or from Java also?
You can call assembly from Android using the Java Native Interface and the Android NDK.
Cedric mentions using the asm keyword, while I prefer to include assembly source code. I have posted a tutorial to do this at my site: http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html
You can download the source code for my example and see how it works. Once you see a functioning example, it is easy to modify it to your needs.
Minimal example with inline and separate source file
Some care has to be taken to not compile the raw assembly under the wrong arch. Here we use:
#ifdef
s on C filesifeq
s onAndroid.mk
This example on GitHub. Tested on Ubuntu 16.04, Android NDK 12, Sony Xperia Z3 D6643 (ARMv7) with 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://stackoverflow.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");
}
}
I think this should be possible when using the NDK that allows you to write C/C++ code packaged in a .apk and then run on the android platform.
With this, you will be able to use the __asm__
keyword in your C code (as mentionned in the release notes of the Revision 5b).
精彩评论