2011-06-28 8 views
14

Nie jestem szczególnie doświadczony w Montażu i ARM, ale udało mi się napisać kilka rutynowych czynności i chciałbym zobaczyć, jak działają na urządzeniach z Androidem wyposażonych w ARM (Nexus S). Jaka jest procedura dołączania pliku kodu zespołu do projektu Android? Czy mogę go wywołać tylko z natywnego kodu lub z Javy?Jak używać kodu ARM Assembly w projekcie Android?

Odpowiedz

10

Możesz połączyć się z zespołem z systemu Android, używając Java Native Interface i Android NDK.

Cedric wymienia za pomocą słowa kluczowego asm, a ja wolę dołączyć kod źródłowy zespołu. Opublikowaliśmy samouczek, aby zrobić to na mojej stronie: http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html

Możesz pobrać kod źródłowy mojego przykładu i zobaczyć, jak działa. Gdy zobaczysz działający przykład, łatwo jest go zmodyfikować do swoich potrzeb.

+0

Bardzo fajne, dzięki. – Phonon

+0

Nie udało mi się jeszcze uruchomić kodu zespołu w moim projekcie, nawet nie wiem, czego potrzebowałem. Ale twój tutorial jest niesamowity i absolutnie warty głosowania. – Wolfen

3

Myślę, że powinno to być możliwe, gdy używasz NDK, który pozwala pisać kod C/C++ zapakowany w plik .apk, a następnie uruchomić na platformie Android.

Dzięki temu będzie można użyć słowa kluczowego __asm__ w swoim kodzie C (jak wspomniano w informacji o wersji w wersji 5b).

+2

Albo można to surowe pliki asemblera. – doron

3

Minimal przykład z inline i oddzielnego źródła pliku

Niektóre opieki ma być podjęta nie skompilować surowego montaż pod niewłaściwym łuku. Tutaj używamy:

  • #ifdef s na plikach C
  • ifeq s na Android.mk

This example on GitHub. Testowany na Ubuntu 16.04, Android NDK 12, Sony Xperia Z3 D6643 (ARMv7) z systemem 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"); 
    } 
} 
Powiązane problemy