How to Use assembly language in Android

Source: Internet
Author: User

Because the android environment is very complex and the framework uses Java, many configurations are required to use C/C ++. More work is required to use assembly.

I am using the latest development tool android4.0, and ndk also supports 4.0. This ndk is obviously different from the old version.

Because I am using Mac OS X, it is much easier to configure it than to shake it down. You don't need to install any third-party tools, so you can directly use the ndk you downloaded.

First, set the target path -- enter the root directory of the ndk in your terminal, and then press ndk_project_path = "<project path you want to compile> ". Press enter and enter export ndk_project_path.

Press enter.

Note that the path after ndk_project_path = needs to be enclosed in quotation marks. Otherwise, it is invalid.

Because ndk supports only the armv5 to armv5te architectures by default, there are two ways to use more advanced features:

1. You have a way to change the value of target_arch_abi to a armeabi-v7a, I tried it myself, wood has succeeded. Therefore, you can use the second method, which is simpler and more convenient:

2. In your ndk directory, find toolchains, and then find the arm-linux-androideabi-x.y.z directory, where you can find the setup. mk file. Find-March = armv7-a, remove the above Shenma # ifdef, the # endif below are also deleted. This ensures that the compiler uses armv7a for compilation.

After completing the above operations, we can first write the assembly in the simplest way, that is, inline assembly --

static int my_thumb(int dummy){    __asm__("movw r0, #1001 \t\n"            "movw r12, #2020 \t\n"            "add r0, r0, r12 \t\n"            "bx  lr");        return dummy;}jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,                                                  jobject thiz ){    my_thumb(0);    return (*env)->NewStringUTF(env, "Hello from JNI !");}

The above code is actually modified based on the "hello-JNI" project that comes with ndk. Finally, you can use ndk-build to compile the program successfully.

 

The above code is compiled by the compiler using thumb/thumb-2 by default. Therefore, all the commands written in the inline assembly are the thumb code.

The following describes how to use arm code and the neon instruction set.

First, modify local_src_files in your android. mk and add the. Neon suffix after the source file name, such as local_src_files: = hello-jni.c to local_src_files: = hello-jni.c.neon.

Note that you can modify the value of local_src_files without modifying the source file name.

Then we add new variables to instruct arm GCC to use the arm instruction set to compile -- local_arm_mode: = arm

In this case, OK. Let's modify the code:

static int my_arm(int dummy){    __asm__("movw r0, #1001 \t\n"            "movw r12, #2020 \t\n"            "add r0, r0, r12 \t\n"            "vdup.32 q0, r0 \t\n"            "bx  lr");        return dummy;}jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,                                                  jobject thiz ){    my_arm(0);    return (*env)->NewStringUTF(env, "Hello from JNI !");}

After using ndk-build, compilation can be successful.

Finally, the last highest-end. Directly write the Assembly file. Ndk has a gas tool. Therefore, it is common sense to write assembly files. Generally, the suffix of the Assembly file is. s, so we can create a XXX. s file.

Then I will create a file named hey. S. Add this file in Android. mk: local_src_files + = hey. S. Neon

We can see that in order to use the neon instruction set in the Assembly file, we also add the. Neon suffix here. The makefile of the assembler also recognizes this identifier.

Edit the hey. s file:

.text
.align 4
.arm

.globl my_real_arm


my_real_arm:

add r0, r0, #256
vmov q0, q1
vdup.32 q0, r0

bx lr

Note that in Apple's assembler, the function name must be prefixed and underlined, while the assembler provided in ndk does not.

Let's modify the hello-jni.c and call this function:

extern void my_real_arm(int i); static int my_arm(int dummy){    __asm__("movw r0, #1001 \t\n"            "movw r12, #2020 \t\n"            "add r0, r0, r12 \t\n"            "vdup.32 q0, r0 \t\n"            "bx  lr");        return dummy;}jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,                                                  jobject thiz ){    my_real_arm(0);    my_arm(0);    return (*env)->NewStringUTF(env, "Hello from JNI !");}

 

Of course, to ensure that the compiler correctly performs a hybrid connection between the arm and thumb instruction sets, we can add-mthumb-interwork to the target_cflags flag in setup. mk.

Test in the Windows operating system, finally found that as long as the application. mk in app_abi in the sign, remove armeabi, leaving only the armeabi-v7a can smoothly use the neon. In this way, you do not need to modify setup. mk or remove the flag in the sample, which is very convenient.

The following lists the available Android. mk compilation configuration files:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := HelloNeonLOCAL_SRC_FILES := helloneon.cLOCAL_ARM_MODE := armTARGET_CFLAGS += -mthumb-interworkTARGET_CFLAGS += -std=gnu11TARGET_CFLAGS += -O3ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)LOCAL_CFLAGS := -DHAVE_NEON=1LOCAL_SRC_FILES += neontest.s.neonLOCAL_ARM_NEON  := trueendifLOCAL_LDLIBS := -lloginclude $(BUILD_SHARED_LIBRARY)$(call import-module,cpufeatures)

When using JNI, you only need to add the JNI folder to your current project directory, and then do it according to the file layout provided in the sample. When you compile with ndk-build (ndk-build.cmd in the cygwin console in Windows), if the build is successful, a libxxx. So file is generated in the libs folder. Use eclipse ADT to re-open your project, and you will find that the JNI file directory and the generated so file are displayed in your project file directory. Of course, you can directly edit the. s Assembly file in Eclipse IDE later, which makes it easier to read.

Finally, if you want to annotate a statement in the android assembler, you must use the annotator --/*... */In c89/90 --/*...*/

The semicolon and the // format introduced in C ++ 98 do not work.

Arm-Linux gcc4.7 and llvm clang3.1 are included in the latest ndk version android-ndk-r8d. However, many of the compilation options of llvm clang3.1 are quite different from those of GCC, so you need to configure the corresponding compilation options when using clang3.1. The default compiler tool chain for this ndk version uses gcc4.6. If you want to use gcc4.7, you can addNDK_TOOLCHAIN_VERSION=4.7To use clang3.1, you can addNDK_TOOLCHAIN_VERSION=clang3.1. The following provides a valid application. mk:

# Build with LLVM Clang3.1#NDK_TOOLCHAIN_VERSION=clang3.1# Build with ARM-Linux GCC4.7NDK_TOOLCHAIN_VERSION=4.7# Build only ARMv7-A machine code.APP_ABI := armeabi-v7a

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.