【问题标题】:Lowercase to Uppercase program not capitalizing when it should小写到大写的程序在应该大写的时候没有大写
【发布时间】:2017-11-24 03:24:08
【问题描述】:

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

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

下面是我的代码

.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

【问题讨论】:

  • cmp si, "a" 看起来不对。您在 SI 中保留指针,而不是字符。提前加载它(到al)并与之比较。另外,add si, cx 看起来不对。您似乎将指针增加了字符串长度的低 8 位,而不仅仅是下一个单词。
  • je checkletter 无论是否被采用,都会跳转或下降到同一个地方,因为分支目标目的地是下一条指令。使用调试器单步执行您的代码并查看执行的位置。大多数条件分支都有相同的错误。
  • 如果您希望其他人阅读您的代码,请评论它,并使用调试器。
  • 我稍微修正了我的程序,现在它只大写了第一个单词的第一个字母。
  • nextline: mov ah, 09h lea dx, newline int 21h 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, "a" jae checkletter2 checkletter2: cmp si, "z" jbe capital checkletter3: inc si dec cx jmp checkletter capital: mov ah, [si] xor ah, 00100000b mov [si], ah jmp loop1 exit: mov ah, 09h mov dx, offset prompt2 int 21h

标签: string assembly dos x86-16


【解决方案1】:
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:

【讨论】:

  • 我试过你所说的取消引用它,我设法做到了。非常感谢你的帮助,伙计
猜你喜欢
  • 2012-11-13
  • 1970-01-01
  • 2011-01-16
  • 2011-10-31
  • 2017-07-18
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
相关资源
最近更新 更多