2011-06-28 41 views
14

我對Assembly和ARM沒有特別的經驗,但是我可以在其中編寫幾個例程,我想看看他們如何在配備ARM的Android設備(Nexus S)上運行。將程序集代碼文件包含到Android項目中的過程是什麼?我只能從本地代碼或Java中調用它嗎?如何在Android項目中使用ARM彙編代碼?

回答

10

您可以使用Java Native Interface和Android NDK從Android調用程序集。

塞德里克提到使用asm關鍵字,而我更喜歡包含彙編源代碼。我已經發布了一個教程,可以在我的網站上執行此操作: http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html

您可以下載我的示例的源代碼並查看它的工作原理。一旦你看到一個有效的例子,很容易修改它以滿足你的需求。

+0

非常酷,謝謝。 – Phonon

+0

我沒有設法在我的項目中運行彙編代碼,但我甚至不知道我可能需要這個。但是,你的教程是驚人的,絕對值得投票。 – Wolfen

3

我認爲這應該是可能的,當使用NDK,它允許你編寫打包在.apk中的C/C++代碼,然後在android平臺上運行。使用此功能,您可以在您的C代碼中使用__asm__關鍵字(如修訂版5b的發行說明中所述)。

+2

或者你也可以包括原始彙編文件。 – doron

3

帶內嵌和單獨的源文件

一些護理具有最小的示例將要採取的不編譯錯誤的拱形下的原始組件。這裏我們使用:

  • #ifdef S於C文件
  • ifeq S於Android.mk

This example on GitHub。使用Android 5.1.1測試Ubuntu 16.04,Android NDK 12,Sony Xperia Z3 D6643(ARMv7)。

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"); 
    } 
}