0

今日の試験でこの質問を受けて、そのためのコードを書きました。どこがうまくいかなかったのか教えてください。

問題:8086マイクロプロセッサの場合、次のタスクを実行するコードを記述します。ユーザーにデータの入力を求め、キーの押下をカウントします。ALPの
実行時に、最初のメッセージが取得されます。「キーの押下をカウントし、エスケープを押して停止します。」(引用符なし)、ユーザーがエスケープを入力すると、2番目のメッセージ「countingkeypresses」が表示され、カウントの結果がBXに格納され、バイナリで表示されます。(データ入力中に)押されたキーも、入力キーは次の行にエコーされます。

解決策:(私が書いた)
.model tiny
.data
text1 db "counting keypresses,press escape to stop $"
text2 db "counting keypresses"
.code
.startup
mov dx,offset text1 ;displaying text1 (i guess so) mov ah,09h
int 21h
and bx,00h
label1 mov ah,01h ;(getting input from user and incrementing bx on every click) int 21h
inc bx
cmp al,1bh ;comparing with 'escape' np label1
mov dx,offset text2 ;if zero then do this i.e display text2 mov ah,09h
int 21h
mov dx,offset bx ;display bx mov ah,09h
int 21h
.exit
end

追加したコメントが適切かどうかわかりません。私のコードは正しくないことはわかっていますが、実際にはまったく正しくありませんが、私は一晩の準備に基づいてこれを書くことができました。 。次の試験で本当に上手くいく必要があるからです。

4

1 に答える 1

1

いくつかの詳細がありますが、基本的な考え方はあります。

まず、あなたはこれを持っています:

cmp al, 1bh
np label1

どういう意味かわかりませんnp。あなたがそこに欲しい命令はおそらくありjnz label1ます。Zフラグが設定されていない場合、つまりユーザーがESCを押さなかった場合、これは分岐します。

カウントを表示するには、次のものがあります。

mov dx,offset bx ;display bx
mov ah,09h
int 21h

それはうまくいきません。実際、レジスタのオフセットを取ることができないので、それはコンパイルされるべきではありません。BXからの値をメモリに格納してから、そのメモリアドレスを出力関数に渡す必要があります。したがって、データ領域に2バイトの値を定義します。

count dw 0  ; counter for output
      db '$' ; terminate output

次に、次のように書くことができます。

move [count],bx
mov dx, offset count
mov ah, 09h
int 21h

カウントをバイナリで出力したいとおっしゃっていましたが、その影響を理解しているかどうかはわかりません。ユーザーが2つのキーだけを押すと、出力はバイナリ0とバイナリ2になり、ボックスとして表示されるか、まったく表示されないか、ファンキーな文字になる可能性があります。int21関数がすべての制御文字をどのように解釈するかを覚えていません。ただし、確かに、ユーザーが13個のキーを押すと、キャリッジリターンだけが表示されます。また、ユーザーが36文字を押すと、出力は...何も表示されません。36は「$」のASCIIコードであり、これが出力ターミネータ文字であるためです。

より良い出力を行いたい場合は、BXの値を16進数に変換するか、16進数(16進数の方が簡単)をASCII文字に変換して出力する必要があります。手元にサンプルがありません。

最後に、レジスタを保存するint21関数の規則が何であるかを思い出せません。BXは通話間で保持されますか?そうでない場合は、push bxint21関数を呼び出す前、および関数pop bxが戻るときに行う必要があります。そうでなければ、あなたのカウントは...「未定義」になります。

于 2011-04-14T04:14:25.423 に答える