今回からロードストア命令に入ります。気が重いです。Armは下手なCISC(多分x86のことだよ)よりもアドレシングモードが複雑怪奇。オペランドによっては特例的な規則もあります。64ビット化したおかげで、バイト、ハーフワード、ワードに加えてダブルワード(SIMD考えるともっと)あり、それに符合がからんで大変。
※「ぐだぐだ低レベルプログラミング」投稿順indexはこちら
最初にお断りしておきますが、対象にしている Arm Cortex-AクラスのCPUの場合、メモリとのロードストアを行う場合、命令の裏側では大物が暗躍しています。
-
- 論理アドレスから物理アドレスへの変換(メモリマネジメント)
- 階層的なメモリサブシステム(キャッシュ)
しかしそいつらに踏み込むと何をやっているのだかわからなくなってしまうので、今はロードストア「命令」に注力。上記のような者どもは「見て見ぬふり」をする所存です。
Arm v8の場合、
-
- ロード命令はメモリからレジスタへのロード
- ストア命令はレジスタからメモリへのストア
というところは、RISCの大原則にのっとってはいます。どこかのCISCのようにメモリからメモリへの転送命令のような「複雑」な命令はありません。しかし、私は言いたいです。
アドレシングモード、どこかのCISCより複雑だろ
と。
アドレシングモードを端的に言えば、メモリのアドレス(論理アドレス)を作るための仕組みです。単純な変数もありますが、配列あり、構造体あり、ポインタありです。強力なアドレシングモードはコンパイラを助ける?のかもしれません。でもRISC-V見たら単純なアドレシングモードで足りてるじゃん。
単独の汎用レジスタへのロード命令で使うアドレシング
まずは今回、実際に命令を動かしてみるのを1回お休みして、単独の汎用レジスタへのロード命令、ニーモニック的にはLDRとかLDURとか、で使われる基本のアドレシングモードを図にしておこうと思いました。整理しておかないと忘れてしまいそうなので。LDRとか書きましたが、オペランドのサイズによってLDRB(符合付バイト)とかLDRUB(符合無バイト)とかサイズと符合が追加され、一族のメンバは多数です。そしてオペランドのサイズはアドレス計算にも一部影響するのです。
なお、アドレス計算に使うオフセットにも符合付、符合無ありますが、オペランドの符合付、無とは無関係です。
ベースレジスタ+オフセット9ビット
9ビットのオフセット即値を符合拡張してベースレジスタに加えてアドレスを生成します。一番分かりやすいなあ。オフセットに何も書かねば0とみなされるので、ベースレジスタオンリもこのモードで表現できます。書式としては以下です。
-
- [base, #imm9]
- [base]
baseのところには、汎用レジスタx0-x30、およびSP(スタックポインタ)を当てはめることができます。ただしSPを使うときはSP独特のアライメント縛りのルールがあるので注意せんとなりません。
ベースレジスタ+オフセット12ビット
12ビットのオフセット即値をゼロ拡張してベースレジスタに加えてアドレスを生成します。オプショナルですが、加えるオフセット即値に下駄(スケール)をはかせることができます。オペランドがワードなら00、ダブルワードなら000です。
-
- [base, #imm12]
ベースレジスタ+オフセットレジスタ32ビット
32ビットのWレジスタが保持するオフセット値を符合付あるいは符合無の拡張を施してベースレジスタに加えてアドレスを生成します。これまたオプショナルで加えるオフセット即値に下駄(スケール)をはかせることができます。
-
- [base, Wm, (S|U)XTW #imm]
段々複雑になってきたなあ。
ベースレジスタ+オフセットレジスタ64ビット
64ビットのXレジスタが保持するオフセット値をベースレジスタに加えてアドレスを生成します。これまたオプショナルで加えるオフセット即値に下駄(スケール)をはかせることができます。
-
- [base, Xm, LSL #imm]
PC相対
64ビットのプログラムカウンタ値に19ビットの即値を符合したものを加えてアドレスを生成します。19ビットの即値には漏れなく下位に00が付加されるので、±1Mバイトの範囲を指定することが可能です。アセンブラ記述上はラベルでメモリを指定します。
-
- label
プリ・インデックスド
9ビットのオフセット即値を符合拡張してベースレジスタに加えてアドレスを生成するのは、最初にでてきたベース+オフセット9ビットと同じです。しかし、こいつがすごいのは、計算結果のアドレスをベースに「書き戻し」できることです。RISCのクセに副作用だぜ。まあ、RISCらしからぬARMの伝統か?表記的には以下のようです。後ろのビックリマーク(エクスクラメーションマーク)が書き戻しのおしるし。
-
- [base, #imm9]!
ポスト・インデックスド
論理アドレスとして使うのは、Base Registerが保持するアドレスです。別途、9ビットのオフセット即値を符合拡張してベースレジスタに加えた値をベースに「書き戻し」します。後から(ポスト)加えるので表記的には以下のようです。
-
- [base], #imm9
こちらにはビックリマークが無いので、つい見過ごしてしまいそうな表記法です(個人の感想です。)
どうこういって、プリもポストも便利だから使ってしまいそうだけれども、それでもRISCか?と問いたいデス。