- ベストアンサー
アセンブリ:FCのファイルオープンについて
- ファイルオープンのファンクションコールについて質問させてください。
- AX=0003 CYとなり、ファイルオープンに失敗してしまいます。
- エディタでアセンブル( DX , 0109 )だと失敗し、デバッグ直打ち( DX , 0200 )だと成功します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
No.1 です。 完全にスッキリはしてないようですが、 一応の解決を見たようで何よりです。 デバッガの動作についてはいずれ勉強してみてください。 命令コードを書き換えて戻すほか、ブレーク時にスタックを消費したりするので、 プログラム中でスタックポインタを変更するような部分も要注意です。 (今時はあまりやらないのかも知れませんが) ソフトウェアデバッグツールに限らず、 どのような方法でその機能を実現しているのか、を知ることは、 不可解な現象に出会った時にその原因を理解し回避するのに 有用です。 ハードウェアの測定機も同様で、思わぬ現象にハマったりしても 測定原理を知ると納得がいく事があります。 ソフトウェアツールや測定機の方式上の影響が避けられない場合は、 その影響を受けずに知りたい事を確認する方法を考え決定する、 というのもテクのひとつです。
その他の回答 (2)
- ngsvx
- ベストアンサー率49% (157/315)
擬似命令を省いているので、確証はありませんが、 FNAME DB'C:\xyz.txt',00H これがどこのセグメントにできているかを確認したほうがいいような気がします。 文章を見ると、コードセグメントに作っているつもりのようですが、 データセグメントにできていたりしませんか? ※masmなんてだいぶやっていないので、外していたらすみません。
お礼
回答ありがとうございます。 擬似命令を省いてしまったため、説明不足になってしまいました。申し訳ありません。 いま試しているのはCOMファイルですので、単一セグメントになります。よってコード、データとも同じセグメント内で定義しています。 ややこしい質問に目を通してくださり、ありがとうございました。
>となり、ファイルオープンに失敗してしまいます。 デバッガ上で実行させると、ですよね? 多分ですが... デバッガ上でプログラムを実行しブレークポイントで止める時、 デバッガが「Go 直前にブレーク用命令に書換え、ブレークしたら元の値に書き戻す」 という事をします。 ブレーク前に空きレジスタにコピーする命令も置いておくとわかるはずです。 今回の例は、INT 21 実行完了後に止めるので、 109番地(ファイルハンドラの先頭)がその位置です。 ファンクションコールで渡す値が 43H のつもりでしょうけど デバッガによって他の値に書換えていて、参照される時には 他の値になっていた為にエラーが発生した、という事でしょう。 普通ブレークポイントはプログラムの続きであり、 そこが一時的に書き換えられいても実行せず止まるだけで、 悪影響はないのですが、 今回のようにその位置が実行中に参照されるような作りだと この理由で不都合を生じます。 他に、実行中にプログラム自身を参照したり書換えるような作りだと、 この件で不都合を起こすことがあります。 対処方法としては、プログラムの続き(というかNOPだけでも)を置くだけです。 手操作で1バイトあけるとよくなった、というのはそういうことです。 ブレーク用命令のコードは忘れましたが、たしか1バイトコードです。 2バイト以上のコードだと、間にジャンプして来たりするとおかしな事になってしまうからです。
お礼
回答ありがとうございます。 勉強しはじめて日も浅いので、言われていることの半分も理解できないのですが、なんとなく理由がわかった気がします。 というのも、いろいろ試しているうちに、ファイルオープン→リードまでを一連で行うと、オープンには 成功するがリードには失敗するということに気づいたからです。 この現象の理由がまったくわからなかったのですが、ご回答くださった内容でおぼろながらも判明しました。先に申しましたが、半分も理解できていない状況ですが、こういった現象に成りうるという事実がわかっただけでも助かりました。 あとNOPについですが、試しに置いてみたのですが、どうもうまくいきませんでした。しかし前述のとおり、プログラムの続きを記述すればファイルオープンはうまくいきました。 現象そのものの原因は「実行中による参照」で間違いなさそうなので、これからいろいろ試してみたいと思います。 ありがとうございました。
補足
検証というか、単にいじくりまわしてるだけですが、なんとかキャリーフラグがセットされずにオープンできるようになりましたので、ご報告だけさせていただきます。 NOP命令ではやはり無理だったので、ご回答を参考にして、 INT21H NOP_MDOKI DB 1 DUP(?) FNAME DB 'C:\xyz.txt',00H と、間にひとつ何かをいれてFNAMEを離せばうまくいきました。 まだデバッグを使いこなせないので原因の究明とまではいきませんが、 とりあえずは前に進めそうです。 ありがとうございました。
お礼
ご助言ありがとうございます。 最近になって原理を知ることの楽しさを覚えてきました。 まだ手探りの状態ですが、時間をかけて勉強していこうと思っています。 ありがとうございました。