2017-10-09 4 views
0

ユーザーにユーザー名の入力を求める質問を解決しようとしています。そのユーザー名が回文文字列の場合(つまり、文字列の逆が元の文字列と同じ場合)、「ユーザー名の再入力」が表示され、入力が再度行われます。そうでない場合は、「OK」と表示され、終了します。私は次のコードを書いており、その中に誤った発見を見つけることができませんでした。誰かが私の間違いを指摘できるなら、大きな助けになるでしょう。前もって感謝します。文字列がパリンドロムアセンブリ言語かどうかをチェック

data segment 
str0 db 'Enter username: $' 
str db '$' 
str1 db 'OK$' 
str2 db 'Retype Username$' 
data ends 

code segment 
assume cs:code, ds:data 
start: mov bx, data 
mov ds, bx 
mov es, bx 
mov bl, '$'  ;terminating point of all strings 
mov cl, 00h  ;counter value in case of loop use 

lea dx, str0 ;to display 'Enter username: ' 
mov ah, 09h 
int 21h 

lab0: lea si, str ;to read the username 
lab: mov ah, 01h 
int 21h 
mov [si], al ;the input is read character by character. To avoid termination after just one character, the characters are read till the end is determined 
inc si 
inc cl 
cmp al, bl 
jne lab 



lea si, str  ;loading string for front end 
dec si 
lea di, str  ;loading string for rear end 
dec di 
lab1: inc di 
cmp [di], bl ;comparing to find '$' 
jne lab1 


lab2: inc si 
mov bh, [si] 
dec di  
cmp [di], bh ;comparing letters from front and rear end 
jne lab3  ;if not equal then not a palindrome 
loop lab2 

lea dx, str2 ;to display 'Retype username' when username is a palindrome 
mov ah, 09h 
int 21h 
jmp lab0 


lab3: lea dx, str1 ;to display 'OK' when the username is not a palindrome 
mov ah, 09h 
int 21h 

mov ah, 4ch 
int 21h 
code ends 
end start 
+0

入力、予想出力、および実際の出力を提供します。また、デバッガを使用する方法も学びます。より良いラベル名を使うべきであり、コメントを書いている間は十分ではありません。 – Jester

+0

PS: 'mov es、dx'は' dx'が設定されていないのでおそらくタイプミスです。私はあなたが 'mov es、bx'をしたいと思う。 – Jester

+1

ようこそスタックオーバーフロー!あなたの質問を編集して、どのようなデバッグを行ったのか教えてください。私はValgrindまたは類似のチェッカー内であなたの[mcve]を実行し、たとえばGDBなどのデバッガーで調査したと思います。完全なコンパイラ警告を有効にしたことを確認してください。ツールはあなたに何を伝えましたか、どの情報が欠落していますか? Eric Lippertの[小さなプログラムをデバッグする方法](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を読んでください。 –

答えて

2
str db '$' 

これは、あなたが入力したユーザー名を保存する場所であると考えられます。
dbの指示は、の1バイトのを予約しています。確かに完全な名前を格納するには十分ではありません。あなたのプログラムで何が起きるのかは、入力ルーチン(ほぼ書き込まれている)が残りのプログラムデータを上書きしてプログラムコードを悪化させ始めるということです。

あなたの入力を保存するためのまともなバッファがで定義されます。入力を終了するには

str db 255 dup (0) 

、あなたは通常を入力します押してください。論理的には、これはコードがチェックする必要があることを意味します。 DOSがあなたに与える価値は13だから、あなたが使った '$'は間違いない!

mov bl, '$'  ;terminating point of all strings 
    mov cx, 0  ;counter value in case of loop use 
lab0: 
    lea di, str  ;to read the username 
lab: 
    mov ah, 01h 
    int 21h 
    cmp al, 13  ;13 is code for carriage return 
    je OK 
    mov [di], al ;the input is read character by character. 
    inc di 
    inc cx 
    jmp lab 
OK: 
    mov [di], bl 

lea si, str  ;loading string for front end 
dec si 
lea di, str  ;loading string for rear end 
dec di 
lab1: inc di 
cmp [di], bl ;comparing to find '$' 
jne lab1 

なぜあなたはあなたの文字列の末尾を検索する必要があるでしょうか?入力の終わりに、インデックス登録者DIはすでに便利に指しています。

lea si, str  ; -> SI=first character 
dec di   ; -> DI=last character 

第一ヒント:あなたはloopを使用しているので、あなたはCXだけでなく、CLをクリアしている必要があります!
2番目のヒント:CXのカウンタがゼロの場合、文字の比較を開始しないでください。
3番目のヒント:CX/2の繰り返しが必要です。

金色のヒント:カウンタはまったく必要ありません。リアインデックスがフロントインデックス以下の場合、ループを終了します(または開始しないでください)。

関連する問題