【问题标题】:Case sorting in mipsmips 中的案例排序
【发布时间】:2013-10-21 10:18:39
【问题描述】:

我有一个程序,它将所有小写字母大写,并将用户在字符串中输入的所有大写字母小写。它通过在字符值中加上或减去 32 来获得所需的字符。我的问题是它不会改变字符串中的任何内容。有什么改变的建议吗?

.data
prompt: .asciiz "\n\nEnter an string of characters: "
result: .asciiz "\n\nHere is the string you entered: "
after_sort: .asciiz "\n\nHere is the string after the case sorting: "
buffer: .space 80
.text

main:

#Prints the prompt string
li $v0, 4
la $a0, prompt 
syscall 

#reads string from user and saves in $a0
li $v0, 8
la $a0, buffer
li $a1, 80
syscall

#Prints the result string
li $v0, 4 
la $a0, result 
syscall

#Prints the string entered by the user
la $a0, buffer 
li $v0, 4
syscall


li $t0, 0 # t0 = i = 0
for_loop:
slti $t1, $t0, 80 # t1 = 1 if and only if t0 < 80
beq $t1, $0, for_loop_done

slti $t2, $a0, 91
li $t3, 1
beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition
bne $t2, $t3, lower

upper:
addi $a0, $a0, 32 #adds 32 to the character value to lowercase it

lower:
subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it

addi $t0, $t0, 1

j for_loop
for_loop_done:

#Prints the result string
li $v0, 4 
la $a0, after_sort 
syscall

#Prints the string entered by the user
la $a0, buffer 
li $v0, 4
syscall

exitProgram:    li $v0, 10  # system call to
    syscall         # terminate program

【问题讨论】:

    标签: sorting mips uppercase lowercase


    【解决方案1】:

    这是我的代码: 效果很好

    .data 
    theString:
    .space 20
    prompt: .asciiz "Enter a string of characters: "
    .text
    main:
    li $v0, 4
    la $a0, prompt 
    syscall
    
    li $v0, 8
    la $a0, theString
    li $a1, 20
    syscall
    
    li  $v0, 4
    syscall
    la $t1,theString
    for:    lb $a0, 0($t1)
    beqz $a0,out  #to find out end of string
    beq $a0,10,out  #to find out end of string
    slti $t2, $a0,91 #if $a0<91 $t2=1
    beq $t2,1,small
    beq $t2,0,capital
    capital:
    subu $a0, $a0, 32
    li $v0,11
    syscall
    addi $t1,$t1,1
    j for
    small:
    addi $a0, $a0, 32
    li $v0,11
    syscall
    addi $t1,$t1,1
    j for
    out: 
    li $v0, 10
    syscall 
    

    【讨论】:

      【解决方案2】:

      很容易忘记,在汇编中你不能这样做:

      if something
          do this
      else
          do that
      

      没有“其他”,只有颤抖转到。

      所以在这段代码中:

      slti $t2, $a0, 91
      li $t3, 1
      beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition
      bne $t2, $t3, lower
      
      upper:
      addi $a0, $a0, 32 #adds 32 to the character value to lowercase it
      
      lower:
      subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it
      
      addi $t0, $t0, 1
      

      当你跳转到upper 时,它会加 32。然后它会减去 32,因为执行会进行到下一行。所以你的代码大写小写,但对大写没有任何作用。

      您需要在 if/then/else 等效项之后添加到第一条指令的跳转:

      upper:
      addi $a0, $a0, 32 #adds 32 to the character value to lowercase it
      j done # No, I don't want to subtract it again!
      
      lower:
      subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it
      
      done:
      addi $t0, $t0, 1
      

      事实上,您可能应该完全摆脱bne - 它是多余的。如果beq 不分支,则不相等。所以这就是成品:

      slti $t2, $a0, 91
      li $t3, 1
      beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition
      
      # Otherwise, it's lower
      subi $a0, $a0, 32 #subtracts 32 from the character value to capitalize it
      j done
      
      upper:
      addi $a0, $a0, 32 #adds 32 to the character value to lowercase it
      
      done:
      addi $t0, $t0, 1
      

      希望有帮助!

      (编辑:@Patrik 也是对的,您需要“取消引用”$a0。我的示例没有考虑到这一点。)

      【讨论】:

        【解决方案3】:

        你使用$a0作为一个字符,比如这里:

        slti $t2, $a0, 91
        

        但它永远不会被字符填充。目前,它包含一个内存地址,而不是一个字符。

        您应该使用lb 加载字符并在使用sb 将其设置为大写/小写后将其存储回来。

        如果您需要代码示例,请随时添加评论。

        编辑:代码相关部分的改动:

        ...
        li $t0, 0 # t0 = i = 0
        for_loop:
        slti $t1, $t0, 80 # t1 = 1 if and only if t0 < 80
        beq $t1, $0, for_loop_done
        
        lb $t4, 0($a0)
        beqz $t4, for_loop_done
        beq $t4, 10, for_loop_done
        slti $t2, $t4, 91
        li $t3, 1
        beq $t2, $t3, upper #if the character value is less than 91 branch to upper addition
        bne $t2, $t3, lower
        
        upper:
        addi $t4, $t4, 32 #adds 32 to the character value to lowercase it
        j done
        
        lower:
        addi $t4, $t4, -32 #subtracts 32 from the character value to capitalize it
        done:
        
        addi $t0, $t0, 1
        
        sb $t4, 0($a0)
        addi $a0, $a0, 1
        
        j for_loop
        for_loop_done:
        
        #Prints the result string
        ...
        

        【讨论】:

        • 我在第 39 行上方添加了 lb $t4, 0($a0),在条件语句分支到的 addi 和 subi 行上将 $a0 切换为 $t4,并添加了 sb $t4, 0( $a0) 低于第 48 行,并在前一个添加的下方添加 $a0, $a0, 1​​。它只是从小写变为大写,而不是相反。有什么建议吗?
        • lb $t4, 0($a0) 应该高出 2 行,高于 slti 测试(并在该测试中将 $a0 更改为 $t4)。此外,在加载指令之后测试空字符:beqz $t4, for_loop_done。最后,在上层之后,下层总是被执行。上层完成后,跳转到下层指令之后。
        • 我试过了,但没用。您能否将您的更改副本发送给我,看看我哪里出错了?
        • 当然,看答案。
        猜你喜欢
        • 2020-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-24
        相关资源
        最近更新 更多