ついに!!!
夢にまで出てきた1.2が表示された!!!!
難しかった!(TOT)
せっかくなので、どんな感じでデバッグをしていたのかを書いてみたい。
一旦落ち着きたいしね(^^)
現象を追え!
最初、おかしな動きに気が付いたのは、ASCIART.BASを読み込んだ後に実行が出来ない事だった。追ってみると、どうやらメモリへのロードは成功しているが、理由は不明だけど実行が出来ないという状態だった。
正直、この状態では全くラチが明かず、とにかく症状を絞り込みたい!
あれこれ試してみて、ロード後にキー入力が入る事に気がついた。
それでは…って事で、読んだBASICプログラムをLISTしてみようとしたところ…プログラムの一部が壊れているが分かった。
ここで少し原因が絞り込めた。
ASCIIセーブされているASCIART.BASをロード後、BASICの中間コードへ変換する際に失敗しているか、または変換は成功しているがLISTしようと文字列へ戻そうとしている時に失敗しているのか、だ。
実行出来ないのはまた別の事情かも知れないが、それは後回し。
まずは目の前のバグを追い掛ける流れに。
ASCIART.BASは大きいので(マシン語レベルの動作を追ってる状態では十分大きい^^;)、もっと小さいプログラムでバグの現象を起こしたい。そしたらこんなパターンが引っかかってきた(先日のブログで載せた写真と同じ)。
現象をたぐり寄せろ!
MBASIC.CMD自体は起動すると自分自身をメモリの上位へ移動させる。
その後、CS=E8F1h、DS=ES=SS=F000hで実行が開始される。
内部での処理対象となるBASICの1行はF000:0305hに入っていて、ここを読み出すプログラムを追い掛ければ良い事になる。そして出来上がったプログラム(中間言語)はF000:0A34hから格納される。
1.5という数字を処理しようとして、整数値[1]から[.]で単精度に変換、次の[5]で倍精度に変換しようとして値を消失させるという、意味不明な動きになっていた。
つまり問題の症状はテキスト→中間コードへの変換途中に起きてる!
変数の内部表現はMicrosoft BASICでおなじみの形式だったため、こちらはすんなり理解ができた。PC-8001のBASIC ROMととても良く似ていて、構造的に同じ?と思えた(どちらもマイクロソフト製ですもんね)。
この頃、GW-BASICのソースコードが公開された事を思い出した。さっそくソースコードをダウンロードしてみたが…今、目の前にある逆アセンブルリストが、ソースのどこに当たるのかを調べるのが一苦労(^^;; そりゃそうか。
でも特徴的なコードからソースの「どこ」を探ることが出来た。
CP/M-86のMBASIC、MS-DOSのGW-BASIC、細かいところの違いはあったけれども、ソース的にはどうやらほぼ同じという事が判明。これで解析が飛躍的にラクになった!\(^O^)/
その後もオーバーフローの算出方法がおかしくなっていたり、パリティの数え方が違っていたり(コード中にパリティで分岐するコードがある)、間違いを直していくけれども完全には直らない。
それにしても今回初めて気が付く8086の仕様もあって驚いた。
・MOVSB/MOVSWでのESはセグメントオーバーライドプリフィックスの影響を受けない
・アドレッシングでBP選択された場合は、SSを採用する
などなど。
意外に根本的なところを理解していない自分に驚いた(^^;;
書いたプログラムソースを何度も見直すが間違いがどうしても見つからない。
仕方ないので、上記のアドレス(F000:0305h)をアクセスした瞬間からBASICの中間コードに変換し終えるまでの実行過程を逆アセンブルし、そこに出てくる命令コードを片っ端から見ていく事に。
おそらく問題はフラグを変化させる系の命令に違いない!
そしてバグは見つかった!
最終的に決定打となったバグは、XORの被演算子が逆になっていたモノだった!
8086にはdビットと言って、被演算子が逆になるという仕様がある。これを意識してプログラムをしていたんだけど、どうも抜けがあったようだ…。
しかも巧妙にもコメントで「dビットが立っているのでsrc,destが逆になる」と書いていた!!(^^;;; どっかのタイミングで逆にしちゃったのかな…汗
イイワケをひとつ。
XORは伝統的?に「XOR AX,AX」という感じに、レジスタに0を入れるコードとして使われるケースが多いため、被演算子の間違いに気づきにくいという事情もあった!
ようやく前に進める…
やっと…やっと1.2が表示された!これを見るために3〜4日悩んだ!
1日中取り組んでるわけじゃなかったけれども、常にアタマにあった(^^;;
久しぶりに苦しんだー(T-T)
さあ、ASCIART.BASを動かしちゃうぜ!!
↑実行するために、実装されてる命令が足りない、というエラー
……orz
じ…地道に頑張るよ!!
それではまた次回!(^-^)ノ