如何在Android中使用汇编语言

因为Android环境很复杂,框架都是Java,使用C/C++需要大量的配置,使用汇编需要更多的工作。

我用的是Android4.0的最新开发工具,NDK是最新支持4.0的。这个NDK和旧版本有一些明显的不同。

因为我用的是Mac OS X,它比个人电脑上的配置要容易得多。你不需要安装任何杂项第三方工具,所以你可以直接使用你下载的NDK。

首先,设置目标路径——在你的终端中输入NDK的根目录,然后键入NDK _项目_路径= " "。输入并输入导出NDK项目路径。

进入汽车。

这里注意,NDK _项目_路径=后面的路径需要引号,否则无效。

由于默认情况下NDK支持的默认编译选项仅支持ARMv5至ARMv5TE架构,因此有两种方法可以使用更高级的功能:

1,你有办法把TARGET_ARCH_ABI的值改成armeabi-v7a。我自己试过,但是没用。所以可以用第二种方法,更简单方便:

2.在您的NDK目录中,找到toolchains,然后找到ARM-Linux-Android ABI-x.y.z目录,在那里您可以找到setup.mk文件。Find -march=armv7-a,去掉上面所有的#ifdef和下面的#endif。这样可以确保编译器使用ARMv7A进行编译。

完成上述操作后,我们就可以用最简单的方式编写程序集了,即内联汇编-

静态int my_thumb(int dummy)

{

__asm__("movw r0,#1001 \t\n "

movw r12,#2020 \t\n

添加r0,r0,r12 \t\n

" bx lr ");

返回虚拟对象;

}

jstring

Java _ com _ example _ hello JNI _ hello JNI _ stringFromJNI(JNIEnv * env,

jobject thiz)

{

my _ thumb(0);

return(* env)-& gt;NewStringUTF(env,“你好,来自JNI!”);

}

上面的代码实际上是基于NDK附带的hello-jni项目修改的。最后可以用ndk-build编译成功。

上面的代码是编译器默认使用Thumb/Thumb-2编译的,所以我写的所有内联汇编的指令都是Thumb代码。

我们将讨论如何使用ARM代码和使用NEON指令集。

首先在你的Android.mk中修改LOCAL_SRC_FILES,在源文件名后面加上一个. neon后缀,比如把LOCAL_SRC_FILES := hello-jni.c改为LOCAL _ SRC _ FILES:= hello-JNI . c . neon。

这里需要注意的是,不需要修改自己的真实源文件名,只需要修改符号LOCAL_SRC_FILES的值即可。

然后我们添加一个新的变量来指示ARM GCC用ARM指令集编译——local _ ARM _ mode:= ARM。

没关系。让我们修改代码:

静态int my_arm(int dummy)

{

__asm__("movw r0,#1001 \t\n "

movw r12,#2020 \t\n

添加r0,r0,r12 \t\n

vdup.32 q0,r0 \t\n

" bx lr ");

返回虚拟对象;

}

jstring

Java _ com _ example _ hello JNI _ hello JNI _ stringFromJNI(JNIEnv * env,

jobject thiz)

{

my _ arm(0);

return(* env)-& gt;NewStringUTF(env,“你好,来自JNI!”);

}

使用ndk-build后,可以正常通过编译。

最后去顶顶。直接编写程序集文件。NDK有气体工具,所以编写汇编文件是合理的。通常,程序集文件的后缀是。所以我们可以创建一个xxx.s文件。

然后我在这里创造了一个名字叫hey.s。在Android.mk中添加这个文件:local _ src _ files+= hey.s.neon。

我们在这里看到,为了在汇编文件中使用NEON指令集,我们还添加了。霓虹后缀在这里。汇编程序的Makefile也能识别这个标志。

我们编辑hey.s文件:

。文本

。对齐4

。手臂

。环球我的真实手臂

我的真实手臂:

添加r0,r0,#256

vmov q0,q1

vdup.32 q0,r0

bx lr

这里需要注意的是,在苹果的汇编程序中,函数名要有前缀和下划线,而NDK提供的汇编程序没有。

让我们修改hello-jni.c并把这个函数放入:

extern void my _ real _ arm(int I);

静态int my_arm(int dummy)

{

__asm__("movw r0,#1001 \t\n "

movw r12,#2020 \t\n

添加r0,r0,r12 \t\n

vdup.32 q0,r0 \t\n

" bx lr ");

返回虚拟对象;

}

jstring

Java _ com _ example _ hello JNI _ hello JNI _ stringFromJNI(JNIEnv * env,

jobject thiz)

{

my _ real _ arm(0);

my _ arm(0);

return(* env)-& gt;NewStringUTF(env,“你好,来自JNI!”);

}

当然,为了保证编译器能够正确混合ARM和Thumb指令集,我们可以在刚才setup.mk中的TARGET_CFLAGS标志中强制添加-mthumb-interwork。

在Windows操作系统中测试后,最终发现只要去掉Application.mk中APP_ABI中的标志,只留下armeabi-V7A,就可以流畅使用neon。这样就不需要修改setup.mk,也不需要去掉Sample中的标志判断,非常方便。

以下是可用的Android.mk编译配置文件列表:

LOCAL_PATH := $(调用my-dir)

包括美元(VARS结算)

LOCAL_MODULE := HelloNeon

LOCAL_SRC_FILES := helloneon.c

本地_ ARM _模式:= arm

TARGET _ CFLAGS+=-m thumb-interwork

TARGET _ CFLAGS+=-STD = GNU 11

TARGET_CFLAGS += -O3

ifeq ($(目标_拱门_ABI),armeabi-v7a)

LOCAL _ CFLAGS:=-d have _ NEON = 1

LOCAL _ SRC _ FILES+= neontest . s . neon

LOCAL_ARM_NEON := true

endif

LOCAL_LDLIBS := -llog

包含$(BUILD_SHARED_LIBRARY)

$(调用导入模块,CPU功能)

当使用jni时,您只需要将JNI文件夹添加到您当前的项目目录中,然后按照示例中提供的文件布局进行操作。用ndk-build编译时(Windows下cygwin控制台使用ndk-build.cmd),如果构建成功,在libs文件夹中会生成一个libXXX.so。然后用Eclipse ADT重新打开您的项目,您会发现jni文件目录和生成的so文件会显示在您的项目文件目录中。当然,您也可以编辑。的汇编文件直接放在Eclipse IDE下,这样更容易阅读。

最后,如果你想在Android汇编程序中注释一个语句,你必须在C89/90-/*中使用注释字符...*/

C++98后面引入的分号和//形式都没用。

在最新的NDK版本android-ndk-r8d中,加入了ARM-Linux GCC4.7和目前流行的LLVM Clang3.1。但是LLVM Clang3.1的很多编译选项与GCC不同,所以使用Clang3.1时需要自己配置相应的编译选项。这个版本的NDK的默认编译器工具链是GCC 4.6版。如果要使用GCC4.7,可以在Application.mk文件中添加NDK _工具链_版本= 4.7;如果要使用Clang3.1,可以在Application.mk中添加ndk _ toolkit _ version = clang 3.1以下是一个合法的Application.mk的内容:

#用LLVM构建Clang3.1

# NDK _工具链_版本= 3.1

#使用ARM-Linux GCC4.7构建

NDK工具链版本=4.7

#只构建ARMv7-A机器码。

APP_ABI := armeabi-v7a

参考上面的Douding.com。

南京宝云安卓培训班正在火热报名中~