- 环境
系统:Ubuntu18.04
工具:Make、NDK17c、adb工具 - 环境准备
下载NDK17c解压到/opt目录下,ndk可用从https://developer.android.google.cn/ndk/downloads/
下载
cd /opt
unzip android-ndk-r7c-linux-x86.zip
如ubuntu没有安装make工具,可用利用下列命令安装:
apt-get install make
如还未安装adb工具,可用如下命令安装:
apt-get install android-tools-adb
- C内嵌汇编简单例子
如深度学习加速优化文集中的gnu C内嵌汇编中的格式说明,C内嵌汇编的格式可以概况为如下:
asm(
代码1
代码2
...
:输入列表
:输出列表
:被更改列表
);
下面举个简单的例子,1+3=4的例子
#随便找个测试目录
cd ~/
mkdir armtest && cd armtest
vim armtest.c
armtest.c
#include <stdio.h>
int main(void){
int abc = 0;
asm(
"mov r1, #1\n\t" //mov指令将立即数1放入r1寄存器
"mov r2, #3\n\t" //mov指令将立即数3放入r2寄存器
"add %[result], r1, r2\n\t" //add指令将r1、r2中的值相加,结果放入变量abc中,这里result是abc的别名
:[result]"=r"(abc) //声明输入来自变量abc
: //无输入
: //无更改列表
);
printf("1+3=%d\n", abc); //打印结果
return 0;
}
为了方便起见,我写了Makefile,当然也可以不写,直接在命令行中用ndk的gcc去编译(注意要链接stl库),为了复用简单,我把Makefile分成两份,一份公用代码提出了以后写其他的Makefile可以简单一些,一份Makefile.def、一份Makefile,Makefile中会包含Makefile.def文件,如下:
~/armtest/Makefile.def
CXX_DEFINES = -DARM_WITH_OMP -DHPPL_STUB_FUNC -DLITE_WITH_ARM -DLITE_WITH_LIGHT_WEIGHT_FRAMEWORK \
-DLITE_WITH_LINUX -DPADDLE_DISABLE_PROFILER -DPADDLE_NO_PYTHON -DPADDLE_WITH_TESTING
LDFLAGS = -latomic -pthread -ldl
SYSROOT_COMPLILE = --sysroot=/opt/android-ndk-r17c/sysroot
SYSTEM_INCLUDES = -I/opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++/include \
-I/opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++abi/include \
-I/opt/android-ndk-r17c/sources/android/support/include \
-I/opt/android-ndk-r17c/sysroot/usr/include \
ifeq ($(ARM_ABI), arm8)
CC = /opt/android-ndk-r17c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-g++
CXX_FLAGS = -funwind-tables -no-canonical-prefixes -D__ANDROID_API__=22 -fexceptions -frtti -std=c++11 -fopenmp -O3 -DNDEBUG -fPIE
CXXFLAGS_LINK = $(CXX_FLAGS) -fpie -Wl,--gc-sections
SYSROOT_LINK = --sysroot=/opt/android-ndk-r17c/platforms/android-24/arch-arm64
SYSTEM_LIBS = /opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a \
/opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++abi.a
INCLUDES = $(SYSTEM_INCLUDES) -I/opt/android-ndk-r17c/sysroot/usr/include/aarch64-linux-android
else
CC = /opt/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++
CXX_FLAGS = -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=softfp -funwind-tables -no-canonical-prefixes \
-D__ANDROID_API__=22 -fexceptions -frtti -std=c++11 -fopenmp -O3 -DNDEBUG -fPIE
CXXFLAGS_LINK = $(CXX_FLAGS) -pie -Wl,--fix-cortex-a8 -Wl,--gc-sections -Wl,-z,nocopyreloc
SYSROOT_LINK = --sysroot=/opt/android-ndk-r17c/platforms/android-22/arch-arm
SYSTEM_LIBS = /opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a \
/opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++abi.a \
/opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a \
/opt/android-ndk-r17c/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libunwind.a
INCLUDES = $(SYSTEM_INCLUDES) -I/opt/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi
endif
~/armtest/Makefile
ARM_ABI = arm7
export ARM_ABI
include ./Makefile.def
CXX_INCLUDES = $(INCLUDES)
CXX_LIBS = $(SYSTEM_LIBS)
armtest: armtest.o
$(CC) $(SYSROOT_LINK) $(CXXFLAGS_LINK) armtest.o -o armtest $(CXX_LIBS) $(LDFLAGS)
armtest.o: armtest.c
$(CC) $(SYSROOT_COMPLILE) $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o armtest.o -c armtest.c
.PHONY: clean
clean:
rm -f armtest.o
rm -f armtest
在armtest目录下执行:
make
此时会在目录下生成一个armtest.o和armtest,armtest就是我们的可执行程序,把armtest adb到手机上执行:
adb push armtest /data/test/
adb shell
cd /data/test/
chmod 777 armtest
./armtest
此时会打印出
image.png
证明我们的例子成功执行。
网友评论