ぐだぐだ低レベルプログラミング(60) ARM64(AArch64)、レジスタ一覧描いてみた

Joseph Halfmoon

前回スマホ上でアセンブラとデバッガを動かし、ARM64(AArch64)のレジスタなど眺めてみました。ARM64はARM32と大分様子が違うので主要なレジスタだけでも一覧しておくべしと図を作り始めてハマリました。調べて図を描いているだけで時間がたちます。レジスタ多すぎ?

※「ぐだぐだ低レベルプログラミング」投稿順indexはこちら

ターゲットCPUのABI(アプリケーション・バイナリ・インタフェース)のドキュメントを読まずにはアセンブラ書きは始まりませぬ。ARM64の場合、Arm社のGithubにおかれている以下のドキュメントを参照しております。

aapcs64.pdf

上記の「薄い」ドキュメントを見ればレジスタの何番をどうやって使ったらよいか、というお作法のようなものは分かります。しかし、アセンブリ言語の命令そのものや動作については何も書かれていないので、以下のドキュメントも「併読」する必要があります。

Arm Architecture Reference Manual  Armv8, for Armv8-A architecture profile

「併読」とさらっと書きましたが、「読んだ人」はお分かりのとおり、読み通すのが辛いドキュメントです。最新版ARM DDI 0847H.a の場合、11530ページほど分量があります。恥ずかしながら断言いたしますぞ

私は読んでません、多分、全部を読むことはないでしょう

インテルx86は大分以前からこんな感じでありました。Armは「まだまし」だったのですが、64ビットになり、改版を繰り返しているうちに、とうとう1万ページを軽く超えてしまった、と。とても全部を把握しきれるものではありませぬ。後は、RISC-Vがこの道を辿らぬように祈るばかりでございます。

汎用(整数)レジスタ

以下に汎用レジスタの全体図を掲げます。64ビット幅のレジスタが31本あります。31と半端なのは、最後の1本(31番)がゼロレジスタという名のレジスタでないものに割り当てられているためです。RISC-Vじゃ、ゼロ番がゼロレジスタでしたが、ARM64では反対の31番だと。

次にレジスタの御名前を述べておかねばなりません。レジスタにはR0からR31という「物理的存在」を示すらしいお名前が付けられているのですが、これとは別に、64ビット幅の論理的な存在としてX0からX30、下32ビットの論理的存在としてW0からW30という「別名」も存在します。アセンブラでプログラムする上ではレジスタのビット幅を意識しないではいられないので、別名の方で書くことになるやと思われます。

しかし、ABI的には使い方のお作法を示す別名もまた存在します。図の後で見て行きます。

GPregs

ABI的な別名を説明する前に、汎用レジスタ31本の外側にある2本の64ビットレジスタに触れないわけにはいきませぬ。

    1. PC プログラムカウンタ
    2. SP スタックポインタ

です。32ビット時代とは宗旨替えした感じで、汎用レジスタの外に鎮座しております。PCは実行している命令のメモリ番地を指し、SPはメモリ上に確保したスタック上位置を指す、という建前であります。

ABI的な別名のその1はLR です。実体はレジスタの30番。リンク・レジスタでございます。これはサブルーチン(関数)呼び出しをしたときに戻り番地(そのときのPCの値)を複製してとっておくのに使ってね、というお約束のための別名です。x86のようなCISCとは違い、RISCは戻り番地を自動でメモリにプッシュするようなサービスはしてくれません。LRに保存するのみです。サブルーチンをネストしたりすると、保存したLRの値(戻り番地)が上書きされてしまうので、「必要があったらスタックにプッシュ」するのはソフトウエアでやらなくてはなりません。ここでSP(スタックポインタ)が使われるっと。

さてABI的な別名のその2はFPです。フレームポインタでありますな。スタック上に確保されるローカル変数領域、スタックフレームを指すためのポインタであります。これを使うか否かは処理系によるかもしれません。

別名のその3とその4は、中央付近、R16,R17などというところにあります。こいつらにはちょっと深入りしたくない感じがしますな。リンカ(リンケージ・エディタ)様がご使用になるのだそうで。意識しなければならなくなったらまた今度と。

なお、R18にも特殊なお役目があり、Platformの情報を持つ番地を指し示しているらしいです。知らんけど。

他はABI上のお役目でザックリ色分けしてみました。最初の8本は引数を与えるのと、戻り値の両方で使うと。R8も戻り値の一種ですが、これは使ってみないと身に染みなそう。R9からR15はテンポラリなので勝手に使って良いみたいです。一方R19からR28は使う際にはどこかに退避させて、戻る前に復旧しないといけない奴ら。

浮動小数レジスタの図も作ったのだけれど、説明が長くなりそうなのでまた次回とさせていただきます。

FPregs

こんなペースでは何時になったらアセンブラ書きに入れるんじゃか?のう?

ぐだぐだ低レベルプログラミング(60) ARM64(AArch64)、スマホでlldb へ戻る

ぐだぐだ低レベルプログラミング(61) ARM64(AArch64)、gdb -tui へ進む