小写到大写的程序不应该大写

时间:2017-11-24 03:24:08

标签: string assembly dos x86-16

我正在编写一个汇编程序,它将我输入的句子中每个单词的第一个字母大写。

我的问题是它没有将单词的第一个字母大写。我的代码出了什么问题?

以下是我的代码

.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 个答案:

答案 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: