如何在Android项目中使用ARM汇编代码?

时间:2011-06-28 12:57:22

标签: android assembly android-ndk arm native-code

我对Assembly和ARM并不是特别有经验,但我能够在其中编写一些例程,我想看看它们是如何在配备ARM的Android设备(Nexus S)上运行的。将汇编代码文件包含到Android项目中的过程是什么?我是否只能从本机代码或Java中调用它?

3 个答案:

答案 0 :(得分:10)

您可以使用Java Native Interface和Android NDK从Android调用程序集。

Cedric提到使用 asm 关键字,而我更喜欢包含汇编源代码。我已在我的网站上发布了一个教程: http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html

您可以下载我的示例的源代码,看看它是如何工作的。一旦看到一个有效的示例,就可以根据需要轻松修改它。

答案 1 :(得分:3)

我认为在使用NDK时,这应该是可行的,它允许您编写打包在.apk中的C / C ++代码,然后在Android平台上运行。

这样,您就可以在C代码中使用__asm__关键字(如修订版5b的发行说明中所述)。

答案 2 :(得分:3)

内联和单独源文件的最小示例

必须注意不要在错误的拱门下编译原始组件。我们在这里使用:

  • #ifdef关于C档案
  • {li> ifeq s Android.mk

This example on GitHub。在Ubuntu 16.04,Android NDK 12,Sony Xperia Z3 D6643(ARMv7)和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");
    }
}
相关问题