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-equipped 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?
In your android app you should be able to use the Java Native Interface/Android NDK to call native code that includes assembly instructions.
Android programs are usually distributed in APK format. This is a special kind of ZIP file, which Android expect to be constructed in a specific way, and should include Java classes (you can write parts of your app using native C/C++ code, but the entry point still needs to be Java).
Assembly language is a low-level programming language for a computer or other programmable device that is closest to the machine language. It is often specific to a particular computer architecture so there are multiple types of assembly languages.
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 on Android.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");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With