2017-05-24 2 views
0

DOSが#を解釈しなかったことを発見したとき、私はDOSで;#の短くて速い通訳をコードゴルフチャレンジとして提出する予定でしたキーを正しく押してください。DOSがなぜ「#」を正しく処理しないのですか(INT 21/AH = 01h)

また挙動を示す小さな例を経由して、それを解剖を開始するために、おそらく良いでしょう:

プログラムに #を入力
org 0x100 
L: 
    mov ah, 01h  ; new input -> al 
    int 21h 
test al, '#'  ; check if the hash key was pressed 
jnz end   ; if it wasn't, jump to the end of program 
    mov dl, '1' 
    mov ah, 02h 
    int 21h   ; otherwise, output `1` 
    jmp L   ; and loop to the beginning 
end: 
    mov ah, 00h  ; end the program 
    int 21h 

、それは偽としてテストし、最後にジャンプします。他の多くのキャラクターと同様です。ただし、D,L,H,Xのいずれか1つ以上を入力すると、1とループを出力します。これは明らかに意図されたものではありません。

私はテストにDosboxを使用したことに注意することが重要です。テストから

は、それが'#'0x230x010x1b(最後の二つのスキャンコードがランダム探索を経て見つけ、2 this pdfのページからのものであった)のために起こります。

正確には、ここでは何が起こっていますか?

+0

あなたが '#'を入力してくださいal' 'の値は何ですか? Keryboardスキャンコードは、必ずしも同じ文字のエンコード、特に拡張キーのエンコードと一致するとは限りません。 –

+0

'xor''' ah'を実行した後、debugxは 'ax'が' 0x0023'であることを知らせます。これは部分的に私が困惑している理由です。 –

+0

ええと、似たような質問(https://stackoverflow.com/a/15182488)でこの正確なトピックを調べました。基本的に、あなたは 'test'と' jnz'命令を悪用しています。彼らは非常に特殊な使い方をしており、どのように行動すべきかについてのあなたの解釈は正しくありません。 –

答えて

2

test a,bはビットを計算し、abを計算し、フラグを設定して結果を破棄します。 test一般的にその目的のためにcmpを使用し、平等のための2つの値を比較するために使用することはできません。

cmp al, '#' 
+0

A) 'test'は私が投げた他の文字をすべて比較するために完璧にうまくいきます(どれが' cmp'と同じ精度で押されたかを検出します)。そしてB) 'cmp'を使うように変更しても問題は解決しません。 –

+0

'test'と' cmp'の違いについては、[this](https://stackoverflow.com/questions/13064809/the-point-of-test-eax-eax)を読んでみてください。限界差) –

+2

@ FinnO'leary "うまくいく"場合、あなたは何か間違ったことをしました。 'test'は、ビットと2つの引数にビットが設定されていないときにのみゼロを返します。これは、両方が等しい場合(つまり、両方がゼロでない場合)は一般的ではありません。あなたは何か別の場所でミスをしたようです。 – fuz

関連する問題