Android NDKとNexus9を使って64bit ARMのアセンブラのHello worldを書いてみた 

今日は、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命令は使えなかった。

[続く]




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.

82 + = 90