何とか庵日誌

本名荒井が毒にも薬にもならないことを書きつづるところ

16進数を10進数にするプログラムその3

 しばらく話題にしてなかったからといって、放り投げたわけではありません。えぇ、忘れてなんかいませんよ。というわけで、その後悪戦苦闘した末、前に晒したプログラムをスリムに書き直すことに成功したのでまた晒します。アセンブリ言語版16進数を10進数化するプログラムの改良版です。


;--- 16 シンスウ ヲ 10 シンスウ ニ スル 2

CHPUT: EQU 00A2H
POSIT: EQU 00C6H

VALUE: EQU 0A000H
MAN: EQU 0A002H
SEN: EQU 0A004H
HYAKU: EQU 0A006H
JU: EQU 0A008H

CURPL: EQU 0A00AH
CURDG: EQU 0A00CH

DIGIT: EQU 0A010H

SZAHYO: EQU 1400H

ORG 9000H

;---- ショキ セッテイ

LD HL,0FFFFH
LD (VALUE),HL ;10シンスウカ スル カズ

LD HL,10
LD (JU),HL
LD HL,100
LD (HYAKU),HL
LD HL,1000
LD (SEN),HL
LD HL,10000
LD (MAN),HL ;テイスウ 10-10000

LD HL,DIGIT
LD B,5
DLOOP: LD (HL),0
INC HL
DJNZ DLOOP ;10シンスウ カク ケタ リセット

LD HL,0A002H
LD (CURPL),HL ;カンザンヨウ テイスウ ノ アドレス

LD HL,0A010H
LD (CURDG),HL ;カンザンゴ 10シンスウ カクノウ ヨウ アドレス

;--- メイン ルーチン

LD B,4 ;ループ カイスウ セッテイ 5ケタ ダカラ 4カイ

;-- スウチ ヲ ヒク

MAIN: PUSH BC ;ループ カウンタ タイヒ

LD BC,(CURPL) ;テイスウ アドレス ヨミコミ
LD A,(BC) ;テイスウ アドレス サンショウ
LD L,A ;カミ 1バイト ダイニュウ
INC BC ;アドレス ヲ オクル
LD A,(BC)
LD H,A ;シモ 1バイト ダイニュウ
INC BC ;テイスウ アドレス ヲ オクル
LD (CURPL),BC ;テイスウ アドレス カキカエ

EX DE,HL ;テイスウ ヲ DE ニ ウツス
LD HL,(VALUE) ;HL ニ 10シン カ スル カズ ヲ ヨミコム

HIKI: OR A ;Cyフラグ リセット
SBC HL,DE ;テイスウ ヲ ヒク
JR NC,DPLUS ;ヒケル ナラ カウンター ゾウカ ショリ ヘ
JR KETAO ;モウ ヒケナイ ナラ ツギノ ケタ ニ ウツル

;-- カク ケタ カウンター ゾウカ

DPLUS: LD BC,(CURDG) ;カンザンゴ スウチ カクノウ アドレス ヨミコミ
LD A,(BC) ;カンザンゴ スウチ ヨミコミ
INC A ;カウンター ゾウカ
LD (BC),A ;スウチ ヲ カキモドス
LD (VALUE),HL ;ヒイタ アト ノ スウチ ヲ カキモドス
JR HIKI ;ヒキザンショリニモドル

;-- ケタ オクリ

KETAO: LD A,(CURDG) ;カンザンゴ スウチ カクノウ アドレス ヨミコミ
;シモ 1バイト ヲ カエルダケデ マニアウノデ コウシテイル
INC A ;アドレス ヲ オクル
LD (CURDG),A ;アドレス ヲ カキモドス

POP BC ;ループ カウンタ フッキ
DJNZ MAIN ;ループ シュウリョウ ハンテイ

;--- イチ ノ クライ

MAINI: LD HL,(VALUE)
LD A,L
LD BC,(CURDG)
LD (BC),A ;アマリ ヲ ダイニュウ スル ダケ

;--- スウジ ヲ ヒョウジ スル

PUTD: LD HL,SZAHYO
CALL POSIT
LD B,5
LD HL,0A010H
LOOP2: LD A,(HL)
ADD A,30H
CALL CHPUT
INC HL
DJNZ LOOP2

RET
END



 リストに註釈が多いのは、組んでいる本人が混乱しないためです(おい)。
 数値を格納しているアドレスを送りながら、定数を参照したり各桁を書き込んだりする処理を組み込むことで、重複していた処理を一つにまとめることができました。前のプログラムが179バイトに対し、こちらは139バイト。その差約40バイトはだいぶ減ったのかあんまり減ってないのか(泣)

 Z80では「LD レジスタ,(数値)」という命令が使えます。数値で示したメモリのアドレスの内容をレジスタに読み込めというものなんですが、これが曲者。間違ってカッコを抜いて「LD レジスタ,数値」と書いてしまって数値そのものをレジスタに代入してしまったり、「LD HL,(ラベル)」と書いたら、ラベルの番地にしまっておいたアドレスの内容ではなく、しまっておいたアドレスそのものを数値として代入しただけなのに気付かなかったりと、何を代入しているのかわからなくなることがしばしばで、整理するのに一苦労でした。

 こちらのプログラムの利点は、65535までの数値をかんたんに扱えるところです。前作ったカウンタープログラムでは、仕様上扱える最大値が9999で、それ以上を扱うには少々手を加える必要がありました。もっとスマートに書けそうな気はするのですが、ひとまずこれで勘弁してくれということで(おい)。