2017-11-24 13 views
0

私が入力した文の各単語の最初の文字を大文字にするアセンブリプログラムを書いています。大文字小文字のプログラムが大文字に変換されないとき

私の問題は、単語の最初の文字を大文字にしないことです。私のコードに何が問題なのですか?

以下は以下の私のコードの更新された部分である私のコード

.model small 
.stack 100h 
.data 
    prompt1 db "Input String: $" 
    prompt2 db "Output String: $" 
    InputString db 21,?,21 dup("$") 
    newline db 10,13,"$" 
.code 
start: 
    mov ax, @data 
    mov ds, ax 

    ; Getting input string 
    mov ah,09h 
    lea dx, prompt1 
    int 21h 

    lea si, InputString 
    mov ah, 0Ah 
    mov dx, si 
    int 21h 

nextline: 
    mov ah, 09h 
    lea dx, newline 
    int 21h 

loop1: 
    mov cl, [si+1] 
    mov ch,0 
    add si, cx 
    inc si 
    dec cx 
    cmp cx, 0 
    je exit 
    jmp checkspace 

checkspace: 
    cmp si, " " 
    inc si 
    je checkletter 

checkletter: 
    cmp si, "a" 
    jae checkletter2 

    checkletter2: 
    cmp si, "z" 
    jbe capital 

capital: 
    mov ah, [si] 
    xor ah, 00100000b 
    mov [si], ah 
    jmp loop1 

exit:  
    mov ah,09h 
    lea dx, prompt2 
    int 21h 

    mov ah, 09h 
    mov dx, offset InputString+2 
    int 21h 

    mov ah, 4ch 
    int 21h 
end start 

です。これで、単語の最初の文字のみを大文字にすることができます。ループに問題があるかどうかはわかりません。私のコードのどの部分が間違っているのか理解してください。大変申し訳ありませんが、デバッガを使ってチェックする方法がわかりません。ありがとうございました。

mov cl, [si+1] 
    mov ch,0 
    add si,2 
    jmp checkletter 

loop1: 
    inc si 
    dec cx 
    cmp cx, 0 
    je exit 
    cmp si, " " 
    je checkletter3 
    jmp loop1 

checkletter: 
    cmp si, 41h 
    jae checkletter2 

checkletter2: 
    cmp si, 5Ah 
    jbe capital 

checkletter3: 
    inc si 
    dec cx 
    jmp checkletter 

capital: 
    mov ah, [si] 
    xor ah, 00100000b 
    mov [si], ah 
    jmp loop1 
+1

は 'CMP SIは、 ""'間違って見えます。キャラクターではなく、SIの中にポインタを置いています。先に 'al'にロードして比較してください。また、 'add si、cx'は間違っています。次の単語だけでなく、文字列の長さの下位8ビットでポインタをインクリメントしているように見えます。 –

+0

'je checkletter'は分岐先が次の命令であるため、分岐しても分岐しなくても同じ場所にジャンプします。デバッガを使用してコードをシングルステップ実行し、実行がどこに行くかを確認します。条件分岐のほとんどに同じバグがあります。 –

+0

誰かに読んでもらうためにコードにコメントし、デバッガを使用してください。 –

答えて

3
cmp si, " " 
cmp si, "a" 
cmp si, "z" 
cmp si, 41h 
cmp si, 5Ah 

上記のすべては、即値とSIのアドレスを比較しています。それらはではなく、SIが指しているアドレスで見つけられることができるバイトを即時と比較するとではありません!それを逆参照する必要があります。

cmp byte [si], " " 
cmp byte [si], "a" 
cmp byte [si], "z" 
cmp byte [si], 41h 
cmp byte [si], 5Ah 

あなたは各単語の先頭を見つけるための最初の必要性を各単語

  • のちょうど最初の文字を大文字の課題を解決するため。これは、各単語の前にある空白をスキップして行います。
  • 位置たら、開始文字がスモールキャップであり、そしてそれがある場合にのみ、あなたはそれが単語の残りの部分は、再びのいずれかの端までスキップさ32
  • を差し引いて大文字に変換するかどうかを確認するために比較しますその行が遭遇するか、またはプロセスが再び上からすべて始まる別の空白が見つかる。

それは次のようになります。

mov cl, [si+1] 
test cl, cl   ;Exit if the input was empty!!! 
jz Exit 
add si, 2   ;Point at first byte 

SkipSpace: 
mov al, [si] 
cmp al, " " 
jne FirstCharacter 
inc si    ;(*) 
dec cl 
jz Exit 
jmp SkipSpace 

FirstCharacter: 
cmp al, "a" 
jb SkipRemainingCharacters 
cmp al, "z" 
ja SkipRemainingCharacters 
sub al, 32   ;Capitalize 
mov [si], al   ; and write back in string 

SkipRemainingCharacters: 
inc si 
dec cl 
jz Exit 
mov al, [si] 
cmp al, " "   ;If not space then it's part of same word 
jne SkipRemainingCharacters 
jmp SkipSpace  ;This could just as easily jump to (*) 

Exit: 
+0

私は逆参照についてあなたが言ったことを試してみた。あなたの助けを借りて大いにありがとう – naomiyx

関連する問題