no-image

[2018/12/19]ARM命令を理解せよ

当記事は書きかけです。

理解が深まり次第追記します。

汎用レジスタ

ARM64は64ビットのレジスタを31個持っており、x0からx30まで名前がつけられています。

実用上必要かどうかは別として、各レジスタはw0 – w30として32ビットのレジスタとして扱うこともできます。

もし0番目のレジスタであるx0をw0として参照しようとした場合、上位32ビットはゼロクリアされ、下位32ビットだけが参照されます。

命令一覧

ロード/ストア

コンピュータは、ほとんどすべての作業をメモリを介して行うので、 ロード/ストア命令はよく使われます。

MOV

レジスタからレジスタへのコピー

MOV             W8, #1
// W8 = 1

LDR

メモリからレジスタへのコピー

LDR X0, Label

のようなコードが考えられますが、このときLabelにはメモリアドレスは入っていません。なぜなら32ビットの命令の中に64ビットのメモリアドレスを詰め込むことができないからです。

Labelには文字通りラベルが入っており、アセンブラがアドレスに変換してくれます。

https://www.mztn.org/dragon/arm6405str.html

LDP

連続したメモリから2つのレジスタに読み込む命令です。 レジスタをスタックから復帰する場合に良く使います。

LDP             X29, X30, [SP,#0x10]
// X29 = Memory[SP + 16]
// X30 = Memory[SP + 16]

LDUR

ベースレジスタの値を変更せず、ベースレジスタにオフセットを加えたメモリからロードします。

LDUR            W9, [X29,#var_4]
// W9 = Memory[X29 + (-4)]
// var_4 = -4

STR

レジスタからメモリへのコピー

STUR

STP

2つのレジスタ(Xt1, Xt2)の内容をメモリアドレスを保持するレジスタXnにオフセットの値を加えたアドレスを先頭とするメモリに書き込みます。

レジスタをスタックに退避する場合によく使われます。

符号付きオフセットのストア

STP Xt1, Xt2, [base {, #simm7}]

分岐

B

プログラムカウンタの値にオフセットを加えたメモリアドレスに分岐します。

BR

分岐先のメモリアドレスを汎用レジスタに格納して実行することで 、汎用レジスタが格納しているメモリアドレスへの無条件分岐を行います。

BL

プログラムカウンタの値にオフセットを加えた メモリアドレスに分岐します。

演算

CMP

レジスタからレジスタ、またはレジスタから定数の減算を行って、演算結果に対応した条件フラグを設定します。演算結果自体を保存しません。

ADD

レジスタとレジスタ、またはレジスタと定数の加算を行います。

ADD             X29, SP, #0x10
// X29 = SP + 16

SUB

レジスタとレジスタ、またはレジスタと定数の減算を行います。