今日は、Android NDKとNexus9を使って64bit ARMのアセンブラのHello worldを書いてみた。
昨日の続きだ。
→ Android NDKとNexus9を使って64bit ARMのアセンブラを試してみた
64bit ARMのアセンブラでHello worldを書くと、このようになった。
ソースコード hello.s (c:\work\jni\hello.s)
.global main .text .align 4 main: sub sp,sp,16 str x30,[sp] adrp x0,message add x0,x0,#:lo12:message bl puts ldr x30,[sp] add sp,sp,16 mov w0,0 ret message: .string "Hello world.\n"
Android.mkファイル(c:\work\jni\Android.mk)は次のようになっている。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello LOCAL_SRC_FILES := hello.s LOCAL_CFLAGS += -pie -fPIE LOCAL_LDFLAGS += -pie -fPIE include $(BUILD_EXECUTABLE)
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
このバッチファイルを実行すれば、ソースコードがビルドされる。
上記のソースコードhello.sは、C言語で記述された
puts("Hello world\n");
というコードをgccに-Sオプションを付けてビルドして得られたソース出力ファイルを参考にした。
puts関数を呼び出すのは、
bl puts
となる。
putsに渡すパラメータとして文字列”Hello world”を定義したmessageのアドレスをx0レジスタに入れておく必要がある。
adrp x0,message add x0,x0,#:lo12:message
と書く。
32bitのARMと比べるとアドレスを指定するのが面倒になっているらしい。
adrp命令とか「:lo12:」という修飾子がよく分からない。
x86 CPUの8086とかの16bit CPUのSegment+Offsetみたいなものだろうか?
—
追記
adrp命令は、4KBのページ内での相対アドレスを得るものらしい。
→ ARM コンパイラ armasm リファレンスガイド Home > A64 汎用命令 > ADRP
→ A64 汎用命令(アルファベット順)
—
さらに追記
adrl疑似命令というのがあり、上記のadrp命令とadd命令のコードを生成するそうだ。
2行書かないといけなかった処理が、1行で簡潔に記述できる。
NDKのアセンブラで試してみたが、サポートしていないようで、adrl命令は使えなかった。
[続く]