11.入門編番外(おわりに)

By 神居 - Posted: 2008/11/11 Last updated: 2010/01/15 - Leave a Comment

アセンブラー基礎講座・入門編のおわりに番外編として実用的なヒントなどを少し。ここまでわかれば「OS/390アセンブラーハンドブック」を読んでもきっとその内容が理解できることと思います。
ハンドブックで述べていますが、アセンブラーのプログラムは「大部分が定石ともいうべきコードの書き方で、大半が構成される」と言えます。ここまでに解説したことはその定石コードを理解するために必要な前提知識でした。OS/390アセンブラーハンドブックには実際の現場で役立ついろいろなヒントが載っていますから、是非活用して下さい。
また実用品のプログラムを書くためには、MVS(MSP、VOS3)のAPIを使うことを避けて通れません。CPU命令だけの実用品プログラムはOS自身の割り込み処理ルーチンでもない限り、我々のレベルで書くことはまずありません。APIについては別のカテゴリーで新たな講座を始めようと思います。


レジスターに1を足す、1を引く

レジスターの値に固定値を加算、減算するには加減算命令の使用が思い浮かびます。しかし内容によっては加減算命令でなくても行う方法があります。

このテクニックはS/370アセンブラー言語では古くから使われています。いずれも命令の動作を応用した「へぇー、そうなんだ」と言うものの代表です。
覚えるとアセンブラーがちょっとわかってきた気がする、小さな幸せですが、実戦では多用されています。
(LA命令は24ビットモードで最大16MB-1、31ビットモードで最大2GB-1までしか扱えないのと減算は出来ないことに注意)
他にもいくつかの「へぇー、そうなんだ」が「OS/390アセンブラーハンドブック」にも載ってます。

ESA/390で追加された新しい命令です。BCTR命令では1しか引けませんが、これなら-32768から+32767の加減算が命令とは別のハーフワード数の定義なしでできます。講座ではS/370アーキテクチャーでの基本的な(伝統的な)命令しか解説してませんが、慣れたら命令リファレンスを見て便利そうな命令は積極的にトライして見て下さい。ただし富士通、日立でも動かすプログラムを作る場合は注意して下さい。特にzアーキテクチャーで追加されたような最新の命令セットはどこまで互換かは動かしてみないとわかりません。


文字列転送

これもESA/390での新しい命令で、MVSTを紹介します。C言語で言うstrcpyです。MVCやMVCLと違い転送する長さを指定しません。文字列の終端文字(NULLターミネート)で長さが認識されます。終端文字も含めて文字列が転送されます。

比較ならCLST命令があります。
ESA/390以降ではUNIXシステムサービスやLINUX自身をサポートするようになったため、LINUXの移植を意識した?と思われる命令がいろいろと追加で実装されています。それらはすべてが公開されていないようですが、一部はアーキテクチャー解説書に載っています。MVSTもCLSTも公開命令です。


わかりやすいロジックを心がけましょう

アセンブラー自体がわかりにくい、と言われてしまえばそれまでですが、わかりやすいプログラムがいちばんです。せっかくアセンブラーを使うのですからクールなロジックを書くのもいいのですが、他人が見てわかるプログラムでないといけません。多少冗長なロジックでも、メモリーをそれなりに使っても、CPUを少し余計に使っても、普通の人が見てわかるロジックにすることが実用品のプログラムでは大切です。LA命令で加算したり、BCTR命令で1を引いたりするのは、命令の動きや機能がわかっていれば簡単に解読できるので、そういうものはいいと考えます。ただしロジックを解読するのに複雑な数学の知識を必要としたり、あまりにもトリッキーなコードは考え物です。書いた人自身が生涯を掛けてメンテナンスするならともかく、ほとんどのプログラムがそうではありません。特にアセンブラー言語でのコーディングが要求されるプログラムはOSの出口ルーチンなどシステムプログラムの部類に入るものがほとんどです。そうでなくてもOSのコントロールブロックを参照したりするため、CPU命令そのものよりはOSの内部動作や構造に関する知識が求められます。命令自身で処理する部分はなるべくシンプルなコードにして保守する人の負担を減らした方がいいと考えます。いくらコメントをきちんとつけても難解なものは難解です。
このあたりはプログラマーのプライドにも関わってくるので賛否両論ありましょうが、自分自身の経験から言えば、やはり「シンプル・イズ・ザ・ベスト」です。そしてこの種の文句は自分の作ったプログラムに対してではなく、他人が作ったプログラムに対して生まれます。そもそも自分が書いたコードですら何年か経って見返した時、「これって何をやってたんだ?、何のために必要だったんだっけ?」「ひどいなぁ」と思うのですから、人が書いたコードなら尚更です。

実用ではたぶん必要としませんが、アセンブラーっぽい例題でひとつ例を挙げます。「ビットの数を数え上げる」

最初の方法はビットを左へ1つずつずらして、溢れたビットを足し算しています。溢れたビットが1なら+1になり、0なら0を足しても変わりません。命令の動きを知っていれば比較的容易に理解できます。
2番目の方法は雑誌に載っていたインテルのx86アセンブラーのサンプルをS/370用に直したものです。32ビットを4ビットずつ8つのブロックに分けて、4ビット単位に1の個数を求め、その考えを32ビットに拡張するものだそうです。4ビットをabcdと4つに並べた時、この4ビットの値は「8a+4b+2c+1d」となるそうです。これから「7a+3b+1c」を引くと、その4ビット中で1になっているビットの個数が求められる、と言うものです。
このページを書いた僕自身がよくわかっていないので、サンプルのコメントもただの命令動作の説明でしか書けませんでした。ちなみにその雑誌の記事では、上記2通りが紹介されていて、アセンブラーならではのコードとして紹介されていたのが「8a+4b+2c+1d」から答えを求めるものでした。その理由は実行する命令数が少ないからです。1番目の方法はソースコードの行数は少ないですがループするので、実際に実行される命令数は131命令になります。2番目の方法はソースコードの行数は多いですがループしないので、実際に実行される命令数は25命令で済みます。CPUの使用量、実行に掛かる時間で言えば、当然2番目の方法に軍配が上がります。

しかし実際の現場仕事としてのプログラムならどうでしょうか?少なくとも私にはよくわかりませんでした。今もわかってませんし突き詰めようとも思ってません。サンプル通りに書いたから動きますが、考え方だけ言われてゼロからコードを書けとなったら、きっとお手上げです。このトピックのネタにしたのも、アセンブラー講座の題材を探すためにめくってた昔の雑誌に載っていたのを見て、「これって(アセンブラーらしいプログラムだよと)言いたいことはわかるけど、こんなのみんなパッと見てわかんのかぁ」と思ったからです。

数学がわかっている人には常識かも知れないし、簡単じゃんこんなの、となるかも知れませんが、実際の現場には数学を知ってる人ばかりとは思えません。たった25命令で処理できるクールなロジックなのは認めますが、普通の人にこんなのわかるかぁ?って思います。CPU使用量は約5倍ですけど、たかが131命令。実際のところ大した違いではありません。数値計算や科学技術計算のプログラムなら別ですが、たいていのシステムプログラムではここまでこだわる必要性はないと考えます。それよりは後で別の人が、普通の人が見てもわかるプログラム、として書く方がいいと思います。アセンブラーらしいとか、CPUの機能を知り尽くしたようなコードもありですが、ソートやデータベースの検索エンジンなど、性能命のソフトはともかく、実用で作るプログラムはわかりやすくないと困ります。そうでなくてもアセンブラーなんてわかんないから困るって言うのが現実ですから。

Posted in S/370アセンブラー講座 • • Top Of Page