アセンブリ言語プログラミングの進めかた
1. 処理方式(アルゴリズム)を明確にする
課題を解決するための処理方式、すなわちアルゴリズムを設計します。処理方式を分かりやすい図に表します。
なお、処理方式を明確にすることは、アセンブリ言語に限らず、どのようなプログラミング言語を使用する場合でもまず最初に行うべきことです。
8ビット数の乗算を例に説明します。
2. アセンブリ言語を意識して処理方式を詳細化する
変数名の割り当て、Cフラグなどのフラグの存在や、フラグ値による条件分岐など、アセンブリ言語を意識して処理方式を詳細に設計します。
-
積の上位8ビットをPH、積の下位8ビットをPLとすれば、
積の上位への被乗数の加算は、PHにMPCDを加算することで実現します。
-
乗数を右シフトすると、押し出される右端のビットはCフラグに格納されます。
Cフラグの値が1のときだけ積上位へ被乗数を加算するには、Cフラグの値が0のときに
条件分岐によって加算をスキップします。
-
16ビットの積の右シフトは、上位8ビット(PH)と下位8ビット(PL)のシフトにより実現します。
-
最後に上記の処理を8回繰り返したか調べ、8回未満のときは乗数の右シフトに戻ります。
8回繰り返したら終了です。
3. 使用できるアセンブリ命令(機械命令)を意識して各処理の実装を詳細化する
プログラミング対象のプロセッサが実行できる命令を意識して、各処理の実行方法を検討します。
つまり、各処理を実行するには、使用可能な命令をどのように組み合わせれば良いかを考えます。
また、省略できる処理がないか確認し、アセンブリ命令数や実行クロックサイクル数の削減を図ります。
-
16ビット積のシフトを8ビットのシフト組み合わせで実現
16ビットの積の右シフトは、まず上位8ビット(PH)をシフトします。押し出される右端のビットはCフラグに入ります。続いて下位8ビット(PL)をシフトしますが、Cフラグが左端から入るシフト命令を使用します。以上よりPHとPL全体を右シフトすることができます。
-
不要な積下位の初期化を省略
積への被乗数の加算は上位8ビット(PH)に対してのみ行います。そして、積を右にシフトすることを8回繰り返します。これにより、積下位8ビット(PL)の初期値は徐々に右に押し出され、最終的には全て失われます。すなわち、PLの初期値は何であっても結果に影響しません。そのため、冒頭の積を0に初期化する部分は、PHのみ0に初期化し、PLの初期化は省略できます。
-
変数を使って繰り返し回数を数える
処理を8回繰り返したことを調べるため、変数COUNTを用意します。COUNTの初期値を8とし、1回繰り返すごとにCOUNTの値を1減じます。COUNT値が0でなければ繰り返しは8回未満、0ならば8回繰り返し済みです。COUNT値を1減じた結果が0か否かをZフラグの値によって判定することができ、Zフラグが1でない場合(COUNT値が0でない場合)に分岐する条件分岐を利用します。
-
変数を適切に初期化
変数COUNTを用いて8回繰り返しを実現するにはCOUNTの初期値は8でなければなりませんが、以下の図を見るとCOUNTを8に初期化する部分がありません。COUNTを8に初期化するように何らかの操作が必要であることが分かります。
-
ラベルを定義
ジャンプや条件分岐がある場合は、ジャンプ先や分岐先のラベルを決めます。
例題では、8回繰り返すためにジャンプする先のラベルと、被乗数の加算をスキップするためのジャンプ先のラベルの2つが必要であり、それぞれ「L0」「L1」とします。
-
プログラム(サブルーチン)の実行前後で維持したい値を考慮
乗算実行により乗数MPLYの値が右シフトされるため、乗算が終了したときに最初の乗数の値が失われます。乗算実行の前後でMPLYの値を維持したい場合には、作業用の乗数記憶領域WMPLYを用意し、乗算開始時にMPLYの値をWMPLYにコピー、以降はWMPLYに対してシフト等の操作を行います。
-
各処理をアセンブリ命令の組み合わせに置き換え
置き換えの例
-
改良
乗数(WMPLY)の右端ビットが0か1かを調べるため、WMPLYを右シフトして右端ビットをCフラグに入れます。その後、Cフラグ値が1ならばPHにMPCDを加算、PHの右シフトを行います。
PHにMPCDを加算するため、ACレジスタにPHを読み出し、ACレジスタにMPCDを加算、ACレジスタの値をPHに書き込み、という手順で行うことができます。次にPHを右シフトするために再びACレジスタにPHを読み出しますが、PHの書き込みと読み出しを連続的に行うことになり、余分な手間に思えます。
そこで、WMPLYを右シフトしたら、まずACレジスタにPHを読み出します。その後でCフラグ値によってMPCDの加算の実行/スキップを判断します。最後にACレジスタを右シフト、ACレジスタをPHに書き込みます。こうすると、PHの読み出しとPHの書き込みは最初と最後の1回ずつだけになります。
ACレジスタにPHを読み出すときにLD命令を使用しますが、LD命令はフラグの値を変更しないという特徴があります。そのため、WMPLYの右シフトにより設定されたCフラグ値は変更なくMPCDの加算実行/スキップの判断に使用することができます。
MPCDの加算をする場合としない場合に共通して行う処理は条件分岐の前に行うこと、そのために各アセンブリ命令が何をして、何をしないかを正しく認識して命令を使用することが重要です。