SSブログ

孤独へ向って突っ走れ (22) [  PC-98x1(補完計画)]

個人用メモ

アセンブラでは高級言語と違い、コードの読みやすさを追求しない。その代わりに処理の速さとサイズ、つまり命令に要するクロック数とバイト数を気にして、時に独特のコーディングをする。ただし使用するプロセッサが改善されると同じ命令に要するクロック数が少なくなったと記憶している(参考:ワイヤードロジック)。それに、時代と共にクロック周波数が格段に高くなり、処理速度が格段に速くなったので、アセンブラで記述してまでも高速化を求める場面は昔に比べると非常に少なくなったと思われる。

趣味でプログラミングをしている私にとっては、アセンブラを使うメリットはもうない。ただ、過去に私がアセンブラを学んだ直後にMASMが売られなくなるという時代的不運があり、充分に学んだり楽しんだりする時間がなく終わってしまったのが悔やまれる。そこで、昔を懐かしむ意味でアセンブラらしいコーディングを見つけたらメモしたいと考えた。

そういう事情なので、ここではプロセッサはいまだに昔懐かしい16ビットが想定される。EAXなどというレジスタは存在しない。32ビットだとデータセグメントをいじらずにプログラミングできるとネットで読んだが、16ビットプログラミングだからDSの値は時として変わる。

私が昔使っていたのがNEC PC-9801シリーズなので、まるで当たり前のようにプロセッサは8086系、アセンブラはMASMの文法になる。

以下は、「テニステニス2」の逆アセンブル結果解析で現在までに私が出会ったアセンブラらしいコーディングだ。

XOR AX,AX
MOV AX,0の代わりに使う。これのメリットは何だったのか、クロック数かバイト数か。今どきネット検索しても命令に必要なクロック数/バイト数の体系的なデータがなかなか見つからず、そもそも上記のようにプロセッサの進化によってそのメリットが無意味になってしまったであろうことは、昔を懐かしむ私としてはちょっと悲しい。むしろ、MOVではフラグレジスタが変化しないがXORではサインフラグ、ゼロフラグ等が影響を受けるということのほうが大事といえるだろう。

SHL AX,1
AXを2倍する。同様に4倍、8倍、16倍、2で割る、4で割る、8で割る、16で割ることができる。8086では乗除算に多くのクロック数を費やしたそうなので、特定の数による乗除算はこうしたほうが良かった。だから昔のプログラムでは普通こうしていると思われる。しかしこれも、上記ワイヤードロジックやクロック周波数の向上により、今ではそれほどのメリットがないのかもしれない。

ADD AX,AX
AXを2倍している。MULを使わずに高速化しているのだろう。しかしこれも(以下同文)

OR AL,AL
一見無意味なコードのように見えるが、これはALの値を変えずに、次に来る条件分岐命令でサインフラグ等を参照して分岐するのに使う。

PUSH DS
POP ES
DSの値をESに入れる。これはコードのバイト数を少なくするために使う。もしもMOVを使うなら、MOV ES,DSは不可なので、一度MOV AX,DSとしてからMOV ES,AXとしなければならない。PUSHとPOPはどちらも1バイトなので、全部で2バイトで済む。ただし処理に必要なクロック数は節約できない。

コメント(0) 

コメント 0

コメントの受付は締め切りました