fortran66のブログ

fortran について書きます。

16進数での 8*4bit = 32bit * 4bit の掛け算。および階乗の計算。

前回は10進法の加算APIを用いましたが、今回は16進数の和ルーチンを使って見ました。
I/O 部分は省略して、掛ける 4bit の数の入力だけで、出力は機械停止後に手動でメモリーを見ることにしました。

メモリーのアサインメントは、プログラム短縮化の為に前回と仕様を変えました。

メモリーの50H−57H にある8ワード(1ワード=4ビット)ビッグエンディアン16進数をIX、58H−5FHにあるものを IY とし、キーボードから入力する4ビット整数を IA とするとき、IY=IA*IX+IY を計算し、さらに IX=IY, IY=0 とします。最終的な結果は IX (50H−57H) に入ります。

計算終了後7セグが点灯します。新たな数を入力すると計算中が終わるまで消灯します。

計算例

はじめにIX=1、IY=0を初期化し、キーボードから1,2,3・・・と順次入力してゆくことで、階乗は普通に12!まで計算できます。

1! 1H
2! 2H
3! 6H
4! 18H
5! 78H
6! 2D0H
7! 13B0H
8! 9D80H
9! 58980H
A! 375F00H
B! 2611500H
C! 1C8CFC00H
D! 17328CC00H
E! 144C362800H

実行時の豆知識としては、6 RUN でデバッグモードで動きます。

ソースコード

IB レジスタを掛ける数のループカウンタに、IX レジスタをキャリーフラグに使っています。
IA レジスタはメモリーアクセス用の受け皿、IY レジスタはメモリーアクセスのインデックス・レジスタになります。

番地 機械語   ラベル ニーモニック コメント
00 0   inp: KA
01 F 0 0   JUMP (inp)
04 E 0   CAL RSTO 7seg. LED off
06 E 4   CAL CMPL loop counter init.
08 9 1   mult_loop: AIA 1
0A F 3 A   JUMP (copy_zero) exit
0D A 0   TIY 0
0F 2   CH
10 A 7   TIY 7
12 5   sum_loop: MA
13 2   CH
14 D 1   CIY 1
16 F 2 2   JUMP (flag_leave_0) no carry
19 2   CH
1A 9 1   AIA 1
1C F 2 3   JUMP (flag_leave_1) carry again
1F 2   CH
20 A 0   TIY 0 carry flag clear
22 2   flag_leave_0: CH
23 B 8   flag_leave_1: AIY 8
25 6   M+
26 F 2 C   JUMP (flag_set) set carry flag 1
29 F 3 0   JUMP (flag_untouch) won't change carry flag
2C 2   flag_set: CH
2D A 1   TIY 1
2F 2   CH
30 4   flag_untouch: AM
31 B 7   AIY -9 loop counter decrement
33 F 1 2   JUMP (sum_loop)
36 2   CH
37 F 0 8   JUMP (mult_loop)
3A A 7   copy_zero: TIY 7 loop counter init.
3C B 8   cz_loop: AIY 8
3E 5   MA copy from
3F E E   CAL DEM- zero clear
41 B 9   AIY -7 move to
43 4   AM
44 B F   AIY -1 loop counter decrement
46 F 3 C   JUMP (cz_loop)
49 1   AO 7seg. LED on
4A F 0 0   JUMP (inp) goto start