Android NDKとNexus9を使って64bit ARMのバイナリを試してみた話の続き。
一昨日書いたソースコードで、インラインアセンブラで記述した2つの整数を加算する部分をアセンブラで書き直してみた。
アセンブラ部分のソースコードadd.s (c:\work\jni\add.s)はこのようになった。
.global addvalues .text .align 4 addvalues: ADD x0,x0,x1; ret;
C言語のソース部分(c:\work\jni\addvalue.c)は、以下の通り。
#include <stdio.h> extern long int addvalues(long int, long int); int main(int argc, char **argv, char **envp) { long int val=addvalues(1234567890123456789L,1L); printf("addvalues = %ld\n",val); return 0; }
アセンブラで書いたaddvaluesという関数を呼び出している。
Android.mkファイルは、このように設定した。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := addvalue LOCAL_SRC_FILES := addvalue.c LOCAL_SRC_FILES += add.s LOCAL_CFLAGS += -pie -fPIE LOCAL_LDFLAGS += -pie -fPIE include $(BUILD_EXECUTABLE)
-pieと-fPIEのコンパイルオプションの追加は、しなくても64bit ARMのバイナリ生成したものは実機で動作したのだけど、一応念のために追加しておいた。
ビルド手順を記述したバッチファイルのbuild.bat (c:\work\build.bat) の内容は前と一緒で以下の通り。
rem =========== environment setting ========== set PATH=%PATH%;c:\android-ndk-r10d\ set ANDROID_NDK_ROOT=c:\android-ndk-r10d\ set NDK_PROJECT_PATH=. echo =========== 64bit build ============ call ndk-build -B V=1 APP_ABI=arm64-v8a pause
このバッチファイルを実行すれば、ソースコードがビルドされる。
ソースコードのadd.sについては、32bit ARM用のものを64bit ARM用に書き直して作成した。
加算の部分について
32bit ARM用だと
ADD r0,r0,r1;
と書くところを、64bit用に書き直すと以下のようにxレジスタを使う。
ADD x0,x0,x1;
また、関数からのリターン命令を書き直す必要がある。
bx lr;
と書くところを、64bit用に書き直すと以下のようにretだけ書けば良い。
ret;
このように書き直して、ビルドしたものが無事に実機(Nexus9)で動作確認できた。