我对 Assembly 和 ARM 不是特别有经验,但我能够在其中编写一些例程,我想看看它们如何在配备 ARM 的 Android 设备 (Nexus S) 上运行。将汇编代码文件包含到 Android 项目中的过程是什么?我只能从本机代码或 Java 中调用它吗?
3 回答
您可以使用 Java Native Interface 和 Android NDK 从 Android 调用程序集。
Cedric 提到使用asm关键字,而我更喜欢包含汇编源代码。我在我的网站上发布了一个教程: http ://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html
您可以下载我的示例的源代码,看看它是如何工作的。一旦你看到一个运行良好的例子,就很容易根据你的需要对其进行修改。
内联和单独源文件的最小示例
必须注意不要在错误的拱门下编译原始程序集。这里我们使用:
#ifdef
s 在 C 文件上ifeq
儿子Android.mk
这个例子在 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");
}
}
我认为在使用允许您编写打包在 .apk 中然后在 android 平台上运行的 C/C++ 代码的NDK时,这应该是可能的。
有了这个,您将能够__asm__
在您的 C 代码中使用关键字(如修订版 5b 的发行说明中所述)。