AArch64アセンブリの練習
#ARM #macOS
ヨロシク・ワールド
簡単なアセンブリプログラミングを書いてコンパイル→リンク→実行してみる
4649(ヨロシク)を返すだけのプログラム。x0レジスタにセットした値が返り値として扱われる
code:4649.S
// return 4649
.text
.globl _prog_start
.p2align 2
_prog_start:
mov x0, 4649
ret
prog_start関数の返り値をターミナルへ表示する。
code:stub.c
#include <stdio.h>
#include <stdlib.h>
extern int prog_start(char *, char *);
int main() {
char *hp, *sp;
sp = alloca(1000000); hp = malloc(4000000);
if (hp == NULL || sp == NULL) {
fprintf(stderr, "malloc or alloca failed\n");
return 1;
}
fprintf(stderr, "sp = %p, hp = %p\n", sp, hp);
int result = prog_start(sp, hp);
fprintf(stderr, "result = %d\n", result);
return 0;
}
実行してみる。result = 4649 が表示されればOK
code:sh
$ gcc 4649.S stub.c -o 4649
$ ./4649
sp = 0x16d85a818, hp = 0x120008000
result = 4649
加算
code:add.S
// return 10 + 20
.text
.globl _prog_start
.p2align 2
_prog_start:
mov x1, 10
mov x2, 20
add x3, x1, x2
mov x0, x3
ret
レジスタの使われ方
(参考: ARM64 ABI 規則の概要 )
https://gyazo.com/adfb0e2bc03beb555e7a07269910f5d1
「x0〜x30」は64ビットレジスタ
「w0〜w30」は32ビットレジスタ
結果レジスタ
「x0」
パラメータレジスタ
「x0」〜「x7」
揮発レジスタ
「x0」から「x17」までは揮発レジスタ
不揮発レジスタ
「x18」から「x30」
その他
「x29/fp」フレームポインタ
「x30/lr」リンクレジスタ
その他のレジスタ
スタックポインタ
「sp」
ゼロレジスタ
32ビットのゼロレジスタ「wzr」
64ビットのゼロレジスタ「xzr」
命令
str
ストア命令。レジスタに格納されてる値をメモリに書き込む
stp
二つのレジスタの値をメモリ中の指定したアドレスへ書き込む
stur
メモリ中の指定したアドレスへレジススタの値を書き込む
(strとの違いがよく分からない...)
https://developer.arm.com/documentation/dui0801/g/A64-Data-Transfer-Instructions/STUR
mov
レジスタからレジスタへの値のコピー、即値のロードなどに利用する
ret
return。指定したレジスタのアドレスに無条件分岐する。レジスタを指定しない場合はリンクレジスタ x30 を指定したことになる
bl
関数呼び出し的な?
必要そうな命令
add (加算)
sub (減算)
and (論理積)
orr (論理和)
lsl (論理左シフト)
asr (算術右シフト)
lsr (論理右シフト)
ldr (ロード、メモリからレジスタへコピー)
str (ストア、レジスタからメモリへコピー)
mov (ムーブ、レジスタからレジスタへコピー)
b (無条件分岐、ラベルを指定)
bl (無条件分岐。リンクレジスタへ戻り先が格納されるため、blで呼び出した関数からretで戻ることができる)
ret (blの呼び出し元へ戻る)
cmp + beq
cmp + bne
cmp + bge (bgt)
cmp + ble (blt)
svc (Supervisor Call、x8にシステムコール番号を、x0からx5にシステムコールの引数を指定)
参考
M1 Macで学ぶARMアセンブリプログラミング
ARM命令セット
http://www.fos.kuis.kyoto-u.ac.jp/~umatani/le4/arm_spec.html
Linux で Arm64 アセンブリプログラミング (05) ストア命令
https://www.mztn.org/dragon/arm6405str.html
Arm64のレジスタ
https://www.mztn.org/dragon/arm6403reg.html
分岐命令
https://www.mztn.org/dragon/arm6408cond.html