【问题标题】:String lowercase to uppercase is duplicating the last letter instead of uppercasing the string字符串小写到大写是复制最后一个字母而不是大写字符串
【发布时间】:2021-12-17 17:56:39
【问题描述】:

我正在制作一个程序,可以将多个小写字母转换为其等效的大写字母。

例如,我想要的输出是:

Input a letter: asddf

The uppercase equivalent of letter asddf is ASDDF

但它只会像这样获取并打印最后一个字符:

Input a letter: asddf

The uppercase equivalent of letter fffff is FFFFF

我该如何解决这个问题?我知道我的代码不正确,但我不知道哪里出错了,因为我还是语言新手。谢谢!

这是我的代码:

  org 100h  

     LEA DX, lowercase           
     MOV AH, 9
     INT 21H
     
     MOV CX, 5
     
     MOV AH, 1                   
     
     @LOOP:
     INT 21H
     
     LOOP @LOOP

     MOV BL, AL                  

     LEA DX, uppercase          
     MOV AH, 9
     INT 21H        
     
     MOV DL, BH
     MOV AH, 02H   
     INT 21h       
     
     MOV CX, 5
      
     MOV DL, BL
     MOV AH, 02H
     
     @LOOP2:
     INT 21h
            
     LOOP @LOOP2 
            
     LEA DX, uppercase_          
     MOV AH, 9
     INT 21H
     
     SUB BL, 20H                 
             
     MOV CX, 5
             
     MOV AH, 2                    
     MOV DL, BL
     
     @LOOP3:
     INT 21H
     
     LOOP @LOOP3   
     

     MOV AH, 4CH                
     INT 21H    
     
   ret
   
   lowercase  db  "Input a letter: $"
   uppercase  db  0AH, 0DH, "The uppercase equivalent of letter$"
   uppercase_ db " is $"  

【问题讨论】:

  • 一次?就像与多个线程并行?如果你想use SIMD to do 16 or 32 characters in parallel,一次处理同一个字符串的多个字符会更有效,然后再处理下一个字符串。如果您只是意味着您有多个字符串并且需要最终在 8086(单线程且没有 SIMD)上完成它们,请遍历它们。无论如何,您的问题标题似乎与您对正在调试的问题的描述不符。

标签: assembly x86-16 emu8086


【解决方案1】:

我知道我的代码不正确,但我不知道哪里出错了

  1. 输入循环应该在某处存储字符
MOV CX, 5
MOV AH, 1                   
@LOOP:
INT 21H
                <<<<
LOOP @LOOP
  1. 第一个输出循环应该检索并使用未修改的存储的字符
MOV CX, 5
MOV DL, BL
MOV AH, 02H
@LOOP2:
INT 21h         <<<<

LOOP @LOOP2
  1. 第二个输出循环应该检索并大写存储的字符
MOV CX, 5
MOV DL, BL
MOV AH, 02H
@LOOP3:
INT 21h         <<<<

LOOP @LOOP3

一般解决方案

在代码中添加一行buffer db 5 dup(0)。然后改变你所有的循环,如下所示:

  • 这是一个循环存储:
  xor  bx, bx
@LOOP:
  
  ...
  
  mov  [buffer + bx], al      ; Store lowercase
  inc  bx
  cmp  bx, 5
  jb   @LOOP
  • 这是一个检索循环
  xor  bx, bx
@LOOP:
  mov  dl, [buffer + bx]      ; Retrieve lowercase
  
  ...
  
  inc  bx
  cmp  bx, 5
  jb   @LOOP

特殊解决方案

由于您已将字符数硬编码为 5,因此您可以使用我在 my previous answer 中向您展示的相同技术。它将允许您一次打印所有内容:

uppercase  db  0AH, 0DH, "The uppercase equivalent of letter$"
uppercase_ db  "????? is ?????$"
;               ^        ^
;               | 9 characters apart
...

  xor  bx, bx
@LOOP:
  mov  ah, 01h                    ; DOS.GetCharacter
  int  21h                        ; -> AL
  mov  [uppercase_ + bx], al      ; Store lowercase
  sub  al, 32
  mov  [uppercase_ + bx + 9], al  ; Store uppercase
  inc  bx
  cmp  bx, 5
  jb   @LOOP

...  Print with DOS.PrintString 09h

【讨论】:

  • 为什么在这里使用sub?您可以强制大写而不破坏已经大写的字符 and al, ~32 清除小写位而不更改已经清除的数字。 What is the idea behind ^= 32, that converts lowercase letters to upper and vice versa?
  • @PeterCordes 我认为 OP 的真正问题不是大写,而是使用内存进行存储。此外,由于他们的代码假定所有小写输入并且不检查数字或标点符号,因此在此阶段使用 andxor 可能会造成混淆。但是对于那些对大写本身感兴趣的人来说,您的链接会很好。
猜你喜欢
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 2011-12-11
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多