@oro-oro
2015-08-18T03:17:27.000000Z
字数 5307
阅读 4009
AndroidARM
C可以调用汇编代码,而Android则通过JNI调用C代码。
所以,可以通过写汇编代码和C,用ndk-build编译成so,让Android调用。
直接使用 \android-ndk-r10d\samples\hello-jni 项目。
将jni目录删除,用Android Studio初始化hello-jni。
代码修改为:
/** Copyright (C) 2009 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.example.hellojni;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;public class HelloJni extends Activity {/* this is used to load the 'hello-jni' library on application* startup. The library has already been unpacked into* /data/data/com.example.hellojni/lib/libhello-jni.so at* installation time by the package manager.*/static {System.loadLibrary("hello-jni");}/*** Called when the activity is first created.*/@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);/* Create a TextView and set its content.* the text is retrieved by calling a native* function.*/TextView tv = new TextView(this);tv.setText(stringFromJNI() + factorialJNI(13));setContentView(tv);}/* A native method that is implemented by the* 'hello-jni' native library, which is packaged* with this application.*/public native String stringFromJNI();/* This is another native method declaration that is *not** implemented by 'hello-jni'. This is simply to show that* you can declare as many native methods in your Java code* as you want, their implementation is searched in the* currently loaded native libraries only the first time* you call them.** Trying to call this function will result in a* java.lang.UnsatisfiedLinkError exception !*/public native String unimplementedStringFromJNI();/*** Multiply the number by 10.** @param input, the number to be multiplied* @return the multiple of the number*/public native int factorialJNI(int input);}
@ This file is jni/multiple.s.text.align 2.global armFunction.type armFunction, %functionarmFunction:@ Multiply by 10. Input value and return value in r0stmfd sp!, {fp,ip,lr}mov r3, r0, asl #3 @ r3=r0<<3=r0*8add r0, r3, r0, asl #1 @ r0=r3+r0<<1=r0*8+r0*2=r0*10ldmfd sp!, {fp,ip,lr}bx lr.size armFunction, .-armFunction
\android-ndk-r10d\samples\hello-jni\jni\hello.c修改,65-71 行是调用汇编函数的代码。
/** Copyright (C) 2009 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.**/#include <string.h>#include <jni.h>/* This is a trivial JNI example where we use a native method* to return a new VM String. See the corresponding Java source* file located at:** apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java*/jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz ){#if defined(__arm__)#if defined(__ARM_ARCH_7A__)#if defined(__ARM_NEON__)#if defined(__ARM_PCS_VFP)#define ABI "armeabi-v7a/NEON (hard-float)"#else#define ABI "armeabi-v7a/NEON"#endif#else#if defined(__ARM_PCS_VFP)#define ABI "armeabi-v7a (hard-float)"#else#define ABI "armeabi-v7a"#endif#endif#else#define ABI "armeabi"#endif#elif defined(__i386__)#define ABI "x86"#elif defined(__x86_64__)#define ABI "x86_64"#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */#define ABI "mips64"#elif defined(__mips__)#define ABI "mips"#elif defined(__aarch64__)#define ABI "arm64-v8a"#else#define ABI "unknown"#endifreturn (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");}/* This stub calls the function. It helps to have a stub like this to* save yourself the hassle of defining the function call in* Assembly. */jint Java_com_example_hellojni_HelloJni_factorialJNI(JNIEnv* env, jobject object, jint input) {/* Try calling some local code */return armFunction(input);}
\android-ndk-r10d\samples\hello-jni\jni\Android.mk修改
# Copyright (C) 2009 The Android Open Source Project## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)# I want ARM, not thumb.LOCAL_ARM_MODE := arm# Name of the local moduleLOCAL_MODULE := hello-jni# The files that make up the source codeLOCAL_SRC_FILES := hello-jni.c multiple.sinclude $(BUILD_SHARED_LIBRARY)
Android.mk
hello-jni.c
multiple.s
准备好这3个文件后,就可以使用ndk-build来编译so了。
其中libs就是包含so的目录,将这个目录,拷贝给Android项目使用即可。
$ ndk-build[armeabi] Compile arm : hello-jni <= multiple.s[armeabi] SharedLibrary : libhello-jni.so[armeabi] Install : libhello-jni.so => libs/armeabi/libhello-jni.so
代码打包地址:http://yunpan.cn/ccaxuNLVH5c9R 访问密码 cff9
参考:
http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html