Как использовать код ARM Assembly в проекте Android? - PullRequest
14 голосов
/ 28 июня 2011

Я не особенно разбираюсь в Assembly и ARM, но мне удалось написать в нем несколько подпрограмм, и я хотел бы посмотреть, как они работают на оборудованном ARM устройстве Android (Nexus S).Какова процедура включения файла кода сборки в проект Android?Могу ли я вызывать его только из нативного кода или из Java?

Ответы [ 3 ]

10 голосов
/ 16 сентября 2011

Вы можете вызвать сборку из Android, используя собственный интерфейс Java и Android NDK.

Седрик упоминает, используя ключевое слово asm , в то время как я предпочитаю включать исходный код сборки. Я разместил учебник для этого на моем сайте: http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html

Вы можете скачать исходный код для моего примера и посмотреть, как он работает. Как только вы увидите работающий пример, его легко модифицировать под ваши нужды.

3 голосов

Минимальный пример со встроенным и отдельным исходным файлом

Необходимо соблюдать осторожность, чтобы не скомпилировать необработанную сборку под неправильной аркой. Здесь мы используем:

  • #ifdef с на 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)

ком / 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");
    }
}
3 голосов
/ 28 июня 2011

Я думаю, что это должно быть возможно при использовании NDK , который позволяет писать код C / C ++, упакованный в .apk, а затем запускать на платформе Android.

При этом вы сможете использовать ключевое слово __asm__ в своем коде C (как упомянуто в примечаниях к выпуску Revision 5b).

...