开发者

How to use ARM Assembly code in an Android project?

开发者 https://www.devze.com 2023-03-16 08:57 出处:网络
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). Wh

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:

  • #ifdefs on C files
  • ifeqs 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");
    }
}


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).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号