0

短いメッセージを表示するはずのコードがあります。関連するコードは次のとおりです。

DATA    SEGMENT 'DATA'
MSG DB  0AH, 0DH, 'Hello, Adam', '$'
CHAR    DB  00H
DATA ENDS

CODE    SEGMENT 'CODE'
PRINT_MSG:
    MOV AH, 09H ;Command to print string of characters
    MOV DX, OFFSET MSG  ;Mov address of message into DX
    INT 21H     ;DOS Interrupt
    JMP WAITING ;Loop back to waiting state
CODE ENDS

出力は次のとおりです。

E:\ece323\software\lab2>MAIN.EXE
?F ^?¶ ? N?   ?               -!-

Hello, Adam-

ここで何が起こっているのですか?

4

5 に答える 5

2

私の推測では、DS はデータ セグメントを指していません。

Int21 関数 0x09 は、DS:DX から文字列を取得します。

DX は 16 ビット レジスタにすぎないことに注意してください。16 ビット範囲外のデータにアクセスするには、セグメント レジスタを使用する必要があります。これらは、データの場合は DS と ES、コードの場合は CS、スタックの場合は SS と呼ばれます (i386 には FS と GS もあります)。

ロード元の正確なアドレスは、16 * segment_register + offset_register で得られます。Int21 は DS の場所を推測できないため、割り込みを呼び出す前に DS をロードする必要があります。

DSレジスタを初期化したことがないので、データセグメントではなくコードを指している可能性が高いと思います。

あなたを交換してみてください

  MOV DX, offset MSG

に:

  LDS DX, MSG  ; Check that, it's been ages since I've written 16 bit code.

残念ながら、私が最後に 16 ビット アセンブラで遊んでから何年も経っているので、チェックすることはできませんが、LDS はうまくいくはずです。

次のようにして、プログラムの起動時に DS を間接的にロードすることもできます。

  MOV AX, SEG DATA  ; check that - can be SEGMENT or so as well.
  MOV DS, AX
于 2008-09-18T13:52:13.450 に答える
0

Nilsは正しいです。int21のこの関数を使用するには、DSレジスタを設定する必要があります。最初にEAX遷移を使用して2番目の部分を試してください。確実に機能するはずです。

また、文字列の後に0文字を入力する必要はありません。9番目の関数はnullで終了する文字列では機能しません。この「$」文字は、0の代わりに機能します。

于 2008-10-06T13:25:59.853 に答える
0

PSPの一部を表示しているようです。これはひょっとして .COM ですか?ORG 100h アセンブラ ディレクティブを忘れると、OFFSET は本来あるべき場所を指し示しません... 興味深いことに、MOV OFFSET から LEA に切り替えるだけでも「動作」します。MASM は、LEA を使用しているときに何をしているかを理解するのに十分スマートですが、OFFSET ではそうではない場合があります (ええ、私はずっと前にこれをすべて難しい方法で学びました... :-) )。

于 2010-12-01T15:24:40.093 に答える
0

次の変更を試してください。

DATA    SEGMENT 'DATA'
ERROR_MSG DB 'DS:DX is wrong'
MSG DB  0AH, 0DH, 'Hello, Adam', '$'
CHAR    DB      00H
DATA ENDS

エラーメッセージが表示された場合、DS:DX が間違っているため、DS が DATA セグメントを指していないか、何らかの理由で「OFFSET MSG」が間違っています...私の asm は錆びていますが、OFFSET の代わりに ADDR を試してください (? )

エラー メッセージが表示されない場合は、実行が PRINT_MSG に到達する前に問題が発生しています。

于 2008-09-18T13:58:06.887 に答える
-1

おそらく、MSDOS プログラム全般 (特に Int 21h 割り込み) が動作するために必要な「リアル」モードで実行していないのではないかと思います。

Windows は、Windows 95 以降、排他的に「保護」モードで実行されています。Windows 2000 以降、コマンド プロンプトは保護モードになっていると思います。

EXE のショートカットを作成してから、ショートカットで互換性オプションを設定してみてください。

于 2008-09-18T13:53:51.450 に答える