アセンブラのマクロ

ここのところ、アセンブラを書くことがけっこうある。

以前、実験用に使っていた無償提供されている開発環境から、

実際の製品に使う開発環境、これは有償で買ったのだが、

この乗換のときにアセンブラの方言の差がかなり大きくて全書換ぐらいになってしまった。

Cのコードもいろいろ書換はあったけど、こちらは限定的である。


その中で以前紹介した1bとか2fのようなラベル表記ができなくなった。

ちなみに bne命令の分岐先1bというのは上にあるラベル1という意味らしい。

逆に下にあるラベル2は2fと書ける。そういうアセンブラの記法があると。

(予約してメモリを書き換える)

こういうのも方言なんですね。

マニュアルを見たのだが、少し表記を変えれば済むというわけではなく、

数字のラベルはすべて名前を付け直すこととなってしまった。


で、アセンブラにはマクロというのがあって、

繰り返し使う命令の並びをあらかじめ書いておくことをやっている。

元々、マクロ内でも数字のラベルが多用されていたのだが、

使えなくなったらまともにラベルを振らないといけない。

それでラベルを振ったらラベルが重複するというエラーが出てくる。


で、こういうのはどうやったら回避できるのかとマニュアルを見たら、

マクロの定義の中でローカルのラベルであることを規定すればよいと。

.macro CHECK_AND_STORE
     local store1, store2, hang, exit
     teq   r0, #1
     beq   store1
     teq   r0, #2
     beq   store2 hang:
     b     hang store1:
     str   #1, [r1]
     b     exit store2:
     str   #2, [r1] exit: .endm

exitとかいうラベルを使うことはけっこう多い気がするけど、

localと書いておけば、マクロを実体化したときに重複しないように処理してくれる。


アセンブラも書いてある順番に命令並べるだけじゃないんですよね。

疑似命令というのもあって、実際には存在しない命令を書けることがある。

ARMだとビットシフトの命令がそうで、MOV命令にビットシフトを付加したものとして処理されたりする。

それはそういう別名みたいなものですけど。

実際に使われる命令を意識して書かれたものもありますけどね。

アドレスをロードするとか、1命令で書けない場合に複数命令に展開したり、

そういう疑似命令もある。1行1命令とは限らないと。


アセンブラを使って記述する理由というのは、

命令の並び順を厳密に決める必要があるというのが理由のほとんどではないか。

割り込みハンドラのレジスタ退避なんていうのはまさにそういう話で、

正しい順番でやらないと割り込み前の状態を保存できなくなってしまう。

スタックを使わないで処理するのもアセンブラで書けば確実である。

そういう用事が済んでしまえばCのコードにジャンプさせてしまう。


今回の開発プロジェクトでアセンブラで書く部分って僕が全部書きそうだけど、

これを見てレビューできる人って他のメンバーにいるのかなというのは気になる。

機械語の挙動を把握してレビューしないといけないわけだからね。

そういう意味でも用事が済んだら早々Cのコードに飛ばすのは重要で、

そうしておけばCのコードは多くの人が平易に理解できるし、

コンパイラはそれを正しく機械語に落とすことが出来るはず。

それでも残るアセンブラ部は極小といいたいところだけど、数行というわけにはいかない。


あと別の話として、既存のシステムのアセンブラで書かれたコードを解読しないといけない話がある。

「これ設計資料あるの?」と聞いたら「ないでしょう」とのことで、

ああやっぱりリバースエンジニアリングかと。

元はアセンブラだけど、書き直すときはCで書いてよいところのはず。

元々のシステムだといろいろ初期化されるまでなのでアセンブラだが、

今回は手順が違うので、Cのコードで書ける部分になるはず。

それはちょっと救いだな。