ぐだぐだ低レベルプログラミング(7) .syntax, コメント、ローカルラベル

一歩引いて眺めたら、アセンブラなんて、どのCPUでも同じようなもんだ、と思います。最初に何か一つのCPUでアセンブリ言語を覚えたら、後は以下同文的に、いろいろなCPUで書けるんじゃないでしょうか(個人の感想です)。ただ、実際にコードを書く段になると、CPU毎の違い、アセンブラ処理系のクセなど「細かい」ところが気になります。また、そこを理解しないと、やりたいことは分かっていても、実際には「どう書いたら良いかね」と手が止まってしまうもの。このところ、不慣れなArmのアセンブラに取り組んでいるので、他のCPUなどから移ってきたときにちょっと戸惑うポイントをメモって行きたいと思います。使用するアセンブラは今回は gas (コマンド名的には as )です。

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

まず最初にちょっと引っかかるのが、コメント文字ですかね。

# と @ と2種類ある

1行全体をコメントとするために行頭にコメント文字を書くときは # でよく、これはgasでは馴染みのあるものです。ところが、行の途中からコメントを書きたいときは @を使わないとならない。ちょっと見苦しい(個人の感想です)。なんでこんなことになるのか、と考えてみると、

Armの場合、即値(イミーディエイト)に#をつける習慣がある

ためじゃないかと思います。

mov r0, #1

などと書くので、#だけでコメントを書くのは無理があったのでしょう。ただ、最近は、以下のような書き方もOKにできるのでした。

mov r0, 1

これを有効にするには、おまじない

.syntax unified

をまず書かねばなりません。これは別に即値数字の書き方を変えるためだけの宣言ではありませんぬ。これこそ

ARM命令 と THUMB命令 を統一した書式で記述する

ための宣言であります。初期のTHUMB命令とARM命令の間には、深くて暗い河があり、どうしても「分けて(divided)」扱う必要があったわけですが、Arm社がTHUMBでも2というやつを推進してくれたおかげで、今ではTHUMB命令側にARM命令同等な命令多数が備わるにいたっています。よって、おなじ1種類の記述でARM命令なのかTHUMB命令なのか実際のコード生成はアセンブラにお任せするという方法が取れるようになったわけです。デフォルトは過去との互換性もありますから「分離方式」ですが、上の .syntax unified と書けば以降は unified方式で書けるようになるわけです。そして unified方式では即値に#つけなくても良い、ということになっている、と。コメント文の書き方は一緒のようですが。

いまさら分離方式でArmのアセンブリコードを覚える必要もあまりないと思うので、問題なければ .syntax unified 宣言しておく方が、いいんじゃないかと思います(個人の感想です)。

さて、お次は gas におけるラベルの書き方です。ラベルはシンボルの1種。。。などと言い始めると抽象化できて頭が良さそうですが、ぶっちゃけ、

番地(アドレス)に貼り付ける名札(ラベル)だ

と思えば、実感がわきます。そんなラベルがコンガラがった一例を御覧いただきましょう。

19行目にある

hex:

これは、普通のラベルですね。hexというとおり、急遽書いてみた 16進文字列を数値に変換するための関数につけたお名前です。関数名なので、当然、外から見えて欲しいので、

.global hex

などと宣言します。これに対して、24行目の「1:」 とか 45行目の「4:」とか数字にコロンつけているだけの「ラベル」共が、gasの

ローカルラベル

というものです。ローカルラベルというのは、

同じお名前が別な場所に何度現れても良い

という代物であります。なんでそんなコンガラがりそうなものがあるかと言えば、アセンブラ書いていたら、コンパイラが勝手にコードをコピーする場合もあれば、インライン展開するときとか、マクロ展開とか、一つのソースコードが、前菜にメインディッシュにと何度も活躍するケースにお目にかかる筈。ごくごく小規模なマイコン向けのアセンブラだとローカルラベルが無い場合があり、そんなときはちょっと困ります(個人の感想です)。あって良かった。ただ、そんな風に重複を許す存在なので、呼ぶ(飛ぶ)ときは、例えば42行目のように

bhi 4f
~途中略~
4:

のように、数字だけのローカルラベルの後ろに f または b という文字をつけると。こうすれば遠くからみても即値とは違うことも分かるし。

fは前方(ソースコードでいったら行数が増える方向)の一番近くにある数字のローカルラベル、bなら後方(ソースコードでいったら行数が減る方向)の一番近くにある数字のローカルラベル、というわけです。この「一番近い」ルールのお陰で、一通りに決まってるわけですな。あんまりこれに頼ると人の目にはコンガラがりかたが半端なくなりますが、アセンブラ的にはちゃんと内部で別々のラベルとして扱ってくれ、その名前は局所に封じ込められるというもの。

次回はアセンブルした結果を動かしてみませう。

ぐだぐだ低レベルプログラミング(6) インラインアセンブラ、gccで書き換えてみれば へ戻る

ぐだぐだ低レベルプログラミング(8) Armらしい命令? へ進む