2011-06-28 39 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"); 
    } 
}