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

发布于 2024-11-17 15:42:52 字数 149 浏览 2 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

奈何桥上唱咆哮 2024-11-24 15:42:52

您可以使用 Java 本机接口和 Android NDK 从 Android 调用程序集。

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

您可以下载我的示例的源代码并查看它是如何工作的。一旦您看到一个功能示例,就可以轻松地根据您的需要对其进行修改。

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.

此岸叶落 2024-11-24 15:42:52

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

必须注意不要在错误的架构下编译原始程序集。这里我们使用:

  • C 文件上的 #ifdef
  • Android.mk 上的 ifeq

这个例子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");
    }
}

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");
    }
}
木落 2024-11-24 15:42:52

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

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文