2014年5月4日 (日曜日)

18:05:44 # Life brainfuck interpreter in ARM assembly を書いた。 C, C++, x86_64 とかいたので次は ARM かなと思って。 ARMのドキュメントがどこにあるのかよくわからずまたてこずったの と gas の記法がまた ARM 用で違うのがつらい。 必要だったドキュメントは ARM の命令セットのドキュメント。 ARM v7-A Architecture Reference Manualが一番よいマニュアルっぽいのだけどARMのサイトではダウンロードするのに登録が必要という。 登録とか必要ないドキュメントもけっこうたくさんあって、 ARM7500FE のデータシートの ARM Processor Instruction Set -- Instruction Set Summary がわかりやすくてよかった。ARM 命令の直交性がよいとかいう人がいるけどまぁわからんでもないという。 一番面食らうのはサブルーチンを呼び出すCALL命令に相当するものがなくて、B 命令のバリエーションでLR(リンクレジスタ)にPCの値を保持するバージョンとLRにジャンプするバージョンがあって、blbx lr を使う。スタック使わなくても良い設計になっているのかな。 あとx86と違うのは、演算はレジスタ間でしかできなくてロードストアはldr/str命令を使うところ。 32bit固定長の命令を使っているため即値命令が16bit代入のmov と movt とPC相対の代入命令とかを使うハメになるので .text の近所に read only data がおいてあって .ltorg ディレクティブでそこにはかせるとか理解を超える挙動が。 あと、あらゆる命令が条件実行できるのだけどそんな機能使える人いるのかな。 関数の呼び出しとかの仕方についてはOABI, EABI とかいろいろあるんだけど今はarmel とよばれるEABIでよいとおもわれる、 ARM ABIにくわしくて、 AAPCSでどのレジスタがどういう意味なのかが解説してある。

ABIでレジスタの意味で、ざっくりメモしたのだと。

r15 == PC (program counter)
r14 == LR (link register)
r13 == SP (stack pointer)
r12 == IP (intra-procedure-call scratch register)
r11 == v8
r10 == v7
r9 == v6, SB, TR, platform register. TR=Thread Register.
r8 == v5
r7 == v4
r6 == v3
r5 == v2
r4 == v1  variable registers
r3 == a4
r2 == a3 argument / scratch register.
r1 == a2
r0 == a1 argument / result/ scratch register

v == callee-saved variable register.
a == caller-saved.

	

二時間くらいドキュメントを読みながらx86のコードをarmの対応す るコードに置き換えてみたら brainfuck コンパイラーがあっけなく 動いてしまった。満足。

Junichi Uekawa

$Id: dancer-diary.el,v 1.94 2009/10/21 14:02:48 dancer Exp $