アセンブリ:FCのファイルオープンについて

このQ&Aのポイント
  • ファイルオープンのファンクションコールについて質問させてください。
  • AX=0003  CYとなり、ファイルオープンに失敗してしまいます。
  • エディタでアセンブル( DX , 0109 )だと失敗し、デバッグ直打ち( DX , 0200 )だと成功します。
回答を見る
  • ベストアンサー

アセンブリ:FCのファイルオープンについて

アセンブリ:FCのファイルオープンについて ファイルオープンのファンクションコールについて質問させてください。 うまく伝えられるか不安なので、いま陥っている現象を順番に書かせていただきます。 まずエディタで、 ---------------------------------- MOV AH , 3DH MOV AL , 00H MOV DX , offset FNAME INT 21H FNAME DB 'C:\xyz.txt',00H ---------------------------------- という簡易なプログラムを記述しました(擬似命令は省いています) これをアセンブルすると、 --------------------------------------- CS:0100 B43D MOV AH,3D CS:0102 B000 MOV AL,00 CS:0104 BA0901 MOV DX,0109 (*注) CS:0107 CD21 INT 21 CS:0109 43 INC BX ・ ・ --------------------------------  となるのですが、このとき AX=0003  CY となり、ファイルオープンに失敗してしまいます。 理由がまったくわからないので、デバックの直打ちで 0200 DB 'C:\xyz.txt' と格納してから、(*注)である命令を MOV DX,0200 に打ちかえれば、 AX=0005  NC となって無事にオープンできるみたいです。 なお、ファイルオープンに限らず、ファイル作成でも同じでした。 エディタでアセンブル( DX , 0109 ) だと失敗し、 デバッグ直打ち( DX , 0200 ) だと成功します。 これはいったい、どういう理由からなのでしょうか? 何冊か本を読んでみたのですが、書かれているのはコードの記述のみなので困っています。 わかる方がおられましたら、ご教授ください。 WINXP:MASM32で行っています。

質問者が選んだベストアンサー

  • ベストアンサー
noname#159916
noname#159916
回答No.3

No.1 です。 完全にスッキリはしてないようですが、 一応の解決を見たようで何よりです。 デバッガの動作についてはいずれ勉強してみてください。 命令コードを書き換えて戻すほか、ブレーク時にスタックを消費したりするので、 プログラム中でスタックポインタを変更するような部分も要注意です。 (今時はあまりやらないのかも知れませんが) ソフトウェアデバッグツールに限らず、 どのような方法でその機能を実現しているのか、を知ることは、 不可解な現象に出会った時にその原因を理解し回避するのに 有用です。 ハードウェアの測定機も同様で、思わぬ現象にハマったりしても 測定原理を知ると納得がいく事があります。 ソフトウェアツールや測定機の方式上の影響が避けられない場合は、 その影響を受けずに知りたい事を確認する方法を考え決定する、 というのもテクのひとつです。

syugyoucyuu
質問者

お礼

ご助言ありがとうございます。 最近になって原理を知ることの楽しさを覚えてきました。 まだ手探りの状態ですが、時間をかけて勉強していこうと思っています。 ありがとうございました。

その他の回答 (2)

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

擬似命令を省いているので、確証はありませんが、 FNAME DB'C:\xyz.txt',00H これがどこのセグメントにできているかを確認したほうがいいような気がします。 文章を見ると、コードセグメントに作っているつもりのようですが、 データセグメントにできていたりしませんか? ※masmなんてだいぶやっていないので、外していたらすみません。

syugyoucyuu
質問者

お礼

回答ありがとうございます。 擬似命令を省いてしまったため、説明不足になってしまいました。申し訳ありません。 いま試しているのはCOMファイルですので、単一セグメントになります。よってコード、データとも同じセグメント内で定義しています。 ややこしい質問に目を通してくださり、ありがとうございました。

noname#159916
noname#159916
回答No.1

>となり、ファイルオープンに失敗してしまいます。 デバッガ上で実行させると、ですよね? 多分ですが... デバッガ上でプログラムを実行しブレークポイントで止める時、 デバッガが「Go 直前にブレーク用命令に書換え、ブレークしたら元の値に書き戻す」 という事をします。 ブレーク前に空きレジスタにコピーする命令も置いておくとわかるはずです。 今回の例は、INT 21 実行完了後に止めるので、 109番地(ファイルハンドラの先頭)がその位置です。 ファンクションコールで渡す値が 43H のつもりでしょうけど デバッガによって他の値に書換えていて、参照される時には 他の値になっていた為にエラーが発生した、という事でしょう。 普通ブレークポイントはプログラムの続きであり、 そこが一時的に書き換えられいても実行せず止まるだけで、 悪影響はないのですが、 今回のようにその位置が実行中に参照されるような作りだと この理由で不都合を生じます。 他に、実行中にプログラム自身を参照したり書換えるような作りだと、 この件で不都合を起こすことがあります。 対処方法としては、プログラムの続き(というかNOPだけでも)を置くだけです。 手操作で1バイトあけるとよくなった、というのはそういうことです。 ブレーク用命令のコードは忘れましたが、たしか1バイトコードです。 2バイト以上のコードだと、間にジャンプして来たりするとおかしな事になってしまうからです。

syugyoucyuu
質問者

お礼

回答ありがとうございます。 勉強しはじめて日も浅いので、言われていることの半分も理解できないのですが、なんとなく理由がわかった気がします。 というのも、いろいろ試しているうちに、ファイルオープン→リードまでを一連で行うと、オープンには 成功するがリードには失敗するということに気づいたからです。 この現象の理由がまったくわからなかったのですが、ご回答くださった内容でおぼろながらも判明しました。先に申しましたが、半分も理解できていない状況ですが、こういった現象に成りうるという事実がわかっただけでも助かりました。 あとNOPについですが、試しに置いてみたのですが、どうもうまくいきませんでした。しかし前述のとおり、プログラムの続きを記述すればファイルオープンはうまくいきました。 現象そのものの原因は「実行中による参照」で間違いなさそうなので、これからいろいろ試してみたいと思います。 ありがとうございました。

syugyoucyuu
質問者

補足

検証というか、単にいじくりまわしてるだけですが、なんとかキャリーフラグがセットされずにオープンできるようになりましたので、ご報告だけさせていただきます。 NOP命令ではやはり無理だったので、ご回答を参考にして、 INT21H NOP_MDOKI  DB 1 DUP(?) FNAME     DB 'C:\xyz.txt',00H と、間にひとつ何かをいれてFNAMEを離せばうまくいきました。 まだデバッグを使いこなせないので原因の究明とまではいきませんが、 とりあえずは前に進めそうです。 ありがとうございました。

関連するQ&A

  • アセンブリ言語で。

    下のようなソースをアセンブルすると 6:error: parser: instruction expected という、エラーが出ます。 mov ah,2 mov dl,DATA int 21h mov ax,4c00h int 21h DATA byte 'A' 6行目に問題があるようなので下のように書き直したらきちんと動作しました。どうして、上のような記述ではうまくいかないのでしょうか?? mov ah,2 mov dl,'A' int 21h mov ax,4c00h int 21h 環境はwindowsXPでnasmとalinkを使っています。 nasmw test.asm -fobj alink test.obj -oEXEとしてアセンブルしました。 わかる方お願いいたします。

  • NASM(独習アセンブラのサンプルソース)について

    独習アセンブラ初版5刷のサンプルソース(リスト6.7、102p)での疑問です 下の方にあるコメントアウトしているputc関数って何のためにあるんですか? どこからも呼び出してないのでいらないと思うのですが… アセンブラはNASMです ※本に書かれてるソースはコメントアウトしてません、コメントアウトしてもアセンブルできました bits 16 org 100h mov dx,sfile mov al,0 mov ah,3dh int 21h jc endquit mov [ifh],ax mov dx,dfile mov cx,0 mov ah,3ch int 21h jc endquit mov [ofh],ax readb: mov bx,[ifh] mov dx,buf mov cx,1 mov ah,3fh int 21h test cx,ax jz endquit jc endquit mov bx,[ofh] mov dx,buf mov cx,1 mov ah,40h int 21h jmp readb endquit: mov bx,[ifh] mov ah,3eh int 21h mov bx,[ofh] mov ah,3eh int 21h mov ax,4c00h int 21h ;putc: ; push ax ; mov ah,2h ; int 21h ; pop ax ; ret ifh dw 0 ofh dw 0 sfile db "srcfile.txt",0 dfile db "destfile.txt",0 buf resb 2 私が思うにリスト6.6(100p)のreadbラベルのところでこれを呼び出してるのでソースを流用して消し忘れてるだけなんでしょうか?

  • アセンブラ、ファンクションコールの使い方

    入力した一文字を改行して表示させるものを作ってます。 以下のものを書いてみまして、 一文字読み取って改行はしますが表示されません。 アドバイス頂けますでしょうか? 環境は MASM 32 です。 name double .model small .stack 100 .data prompt db 0ah,0dh,"? $" .code start: mov ax, @data mov ds, ax lea dx, prompt mov ah, 9 ;output string int 21h mov ah, 1 ;get keyboard input and store into al int 21h mov dl, 0ah mov ah, 2 int 21h mov dl, 0dh mov ah, 2 int 21h mov dl, al mov ah, 2 ;output char from dl int 21h mov ax, 4c00h ;exit int 21h end start

  • アセンブリのファイル操作のエラーに関する質問

    使っている開発環境は、MSDOSプロンプトの、「DEBUG」コマンドなんですが以下のプログラムを実行した所 「共有違反です。読み取り中のドライブ:C  中止(A) 再試行(R) 失敗(F)?」 とエラーメッセージが出ました 私は、失敗を選んだのですが、AXに、エラーコードの「5」 が戻されていました、 これは、MSDOSのDEBUGコマンドが強制的にエラーを起したのでしょうか、それとも私が書き間違えたエラーなのでしょうか ↓が、アセンブル(コンパイル)しようとしたソースです (ソースをかくまえの、コマンドによるメモリへのストアも含む) E 200"C:\testtest0" A 100 MOV AH,3C MOV DX,200 MOV CX,0 INT 21 この後に「G]コマンドで実行

  • アセンブラ、ビデオモード al 13h でマウスのポインタを表示

    mov ah, 0 mov al, 13h int 10h のモードでマウスのポインタを表示することは可能でしょうか? 以下のコードを書いてみまして、ビデオモードを設定しない場合は Alt + Enter でフルスクリーンにすればポインタが表示されます。 環境は masm32、interrupt のリストはこちらです ↓ http://www.ctyme.com/intr/int.htm ---------------------------------- .model small .stack 100h .data .code start: mov ax, @data mov ds, ax mov ah, 0 ; set video mode mov al, 13h int 10h ; mov ax, 0 ; reset ; int 33h ; mov ax, 20h ; int 33h mov ax, 1 ; show mouse pointer int 33h mov ah, 1 ; wait for key int 21h mov ah, 0 ; restore video mode mov al, 3h int 10h mov ax, 4c00h ; exit int 21h end start

  • 文字を表示するファンクションコールについて

    アセンブリ言語プログラムについての質問です。 MASM32を使っています。AXレジスタの数値をah→表示、al→表示というプログラムを作ったのですが、al→表示の部分がうまく機能しせません。以下にプログラムを書きます。 (1)mov ax,3132h (2)mov dl,ah (3)mov ah,02h (4)int 21h (5)mov dl,al (6)mov ah,02h (7)int 21h (分かりやすく番号をふっています。実際のプログラムには番号はふっていないです。) 具体的どこが機能しないかというと、(5)番目の命令のalレジスタの内容をdlレジスタに転送するという命令が機能しません。デバックのT命令で確認したところ(5)番目の命令がNOPとなっていました。 このプログラムを実行すると結果的に表示されるのは「11」という文字です。(本来は12と表示したい。) 質問 なぜ(5)番目の命令がnopとなるのでしょうか?

  • コマンドプロンプトのデバッガ

    以下のように,コマンドプロンプトのDEBUGコマンドでアセンブリ言語を書いたのですが,COMファイルとして保存する方法(http://wisdom.sakura.ne.jp/programming/asm/assembly29.html)が分かりません。お願いします! debug a 100 mov ah,a mov dx,9100 mov byte ptr[9100],20 int 21 ret a 200 sub bl,30 ret a 300 mov bl,byte ptr[9103] cmp bl,2b je 318 cmp bl,2d je 31a cmp bl,2a je 31a cmp bl,2f je 31a add al,dl ret a 400 mov ah,0 mov dl,a div dl mov byte ptr[9200],0d mov byte ptr[9201],0a add al,30 mov byte ptr[9202],al add ah,30 mov byte ptr[9203],ah mov byte ptr[9204],24 mov ah,9 mov dx,9200 int 21 ret a 9000 call 100 mov bl,byte ptr[9102] call 200 mov al,bl mov bl,byte ptr[9104] call 200 mov dl,bl call 300 call 400 mov ah,4c mov al,0 int 21 g =9000 9021

  • MASM実行エラー

    mov dx, 1234 mov ah, 09h int 21h これでMS-DOSプロンプトがピーと鳴ってしまいました。 mov dx, ラベル のようにラベルを使う以外の方法はありますか?

  • c言 ファイルのオープンについて

    #include <stdio.h> int main(void) { int ch; FILE *fp; char fname[64]; printf("ファイル名:"); scanf("%s",fname); if((fp=fopen(fname,"r"))==NULL) printf("ファイルをオープンできません。\n"); else{ while((ch=fgetc(fp))!=EOF) putchar(ch); fclose(fp); } return(0); } ファイル名は20130603.cで、実行ファイル(exe)と同じディレクトリに入れてあるのに、このプログラムでファイルをオープンできないのです。 このプログラムを実行するために必要なファイルの作成法と、例としてのファイルの内容、実行結果など、教えていただきたいのです。 色々調べてみたのですが、解決法がイマイチ見つかりませんでした。 どうかよろしくお願いします。

  • アセンブラを実行したいのですが

    パソコン初心者です。 Windows XPにアセンブラ「NASM」をダウンロードしました。 コマンドプロンプトで簡単なプログラムを実行しようと思います。 以下がプログラムです。 ; dispchar.asm mov ah,02 mov dl,31h int 21h mov ah,4ch mov al,0 int 21h コマンドプロンプトに「; dispchar.asm」と入力すると、内部コマンド、外部コマンドまたは操作可能なファイル、バッチファイルとして認識されていません」と出ます。 同様に、「mov ah,02」から入力しても同様のコメントが返ってきます。 プログラムを実行するにはどうすればよいでしょうか?

専門家に質問してみよう