简体   繁体   English

mips汇编程序-从字符串中按索引删除字符

[英]mips assembler - delete a character by index from string

I need it for my homework. 我需要它做作业。 User inputs a string and index of char he'd like to erase. 用户输入要删除的char的字符串和索引。 I should return string without this char and without space. 我应该返回不带此字符和空格的字符串。 The last thing I've tried it's to copy characters one by one from one string to another and skip the char that I want to delete. 我尝试过的最后一件事是将字符从一个字符串一个接一个地复制到另一个字符串,然后跳过要删除的字符。 Example: received string "asdfghjkl" and I want to delete char No3 so I should print string "asfghjkl" but instead it looks like "ssfggggggggggggggggggggggggggggggggggggggg.......". 示例:收到字符串“ asdfghjkl”,我想删除char No3,因此我应该打印字符串“ asfghjkl”,但看起来像是“ ssfggggggggggggggggggggggggggggggggggggg .......”。 I tried different combinations and played with counters, tried .space 128 instead of n etc. but with no success. 我尝试了不同的组合并使用了计数器,尝试使用.space 128而不是n等,但是没有成功。 Code runs in QtSpim Thanks 代码在QtSpim中运行谢谢

the MIPS code is: MIPS代码为:

.data
# $s0   str1
# $s7   str2

str1: .space n
str2: .space n
msg1:   .asciiz "Input your string\n\n"
msg2:   .asciiz "\nNumber of character to erase "
err:    .asciiz "error in number"
result: .asciiz "\nthe new string is\n\n"

.text

main:   
    la $a0, str1
add $s0, $a0, $0
la $a0, str2
add $s7, $a0, $0
la $a0, msg1    #Input your string
li $v0, 4
syscall

li $v0, 8   #Read input string to $s0
syscall
move $s0, $a0

la $a0, msg2    #Input your string
li $v0, 4
syscall 

li $v0, 5   #Read Number of character to erase to $s1
syscall
add $s1, $v0, $0    #Number of character to erase $s1==
addi $t0, $s1,-1    #Number of character to erase $t0
addi $t1, $0, 127   #$t1=127 counter

findchar:

ret:
lbu $t5, 0($s0) #copy chars from string1 to string1
sb $t5, 0($s7)

addi $t1, $t1, -1   #counter of whole string1
addi $t0, $t0, -1   #counter of the character we want to erise

addi $s0, $s0, 1    #move to next char
addi $s7, $s0, 1    #move to next char
beqz $t0, shift     #if we at char we want to erise, 
                            #we skip it in string1 and continue
beqz $t1, print     #if string is finished, print result
j findchar



print:  addiu $s7, $s7, -127    #return to first char of new string
la $a0, 0($s7)      #and print it
li $v0, 4
syscall



end:    li $v0, 10
syscall
shift:  addi $s0, $s0, 1    #skip erised char in string1
addi $t1, $t1, -1

j ret           #continue copy chars from string1 to string2

&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&

Thank you. 谢谢。 After the answer I've changed a code but then the "length" value I get from $a1 is 0x7ffff550. 答案之后,我更改了代码,但从$ a1获得的“长度”值为0x7ffff550。 It's my main issue - I'm not succeeding to get the right length. 这是我的主要问题-我没有成功获得正确的长度。

.data
# $s0   str1
# $s7   str2

    str1: .space n
    str2: .space n
    msg1:   .asciiz "Input your string\n\n"
    msg2:   .asciiz "\nNumber of character to erase "
    err:    .asciiz "error in number"
    result: .asciiz "\nthe new string is\n\n"
.text

main:
    la $a0, str1
    add $s0, $a0, $0
    la $a0, str2
    add $s7, $a0, $0
    la $a0, msg1    #Input your string
    li $v0, 4
    syscall

    li $v0, 8   #Read input string to $s0
    syscall
    move $s0, $a0
    move $s6, $a1

    la $a0, msg2    #Input your Number of character to erase
    li $v0, 4
    syscall 
    li $v0, 5   #Read Number of character to erase to $s1
    syscall
    add $s1, $v0, $0    #Number of character to erase $s1==

    addi $t0, $s1,-1    #Number of character to erase $t0
    add $t1, $s6, $0    #$t1= counter of length

findchar:

ret:
    lb $t5, 0($s0)  #copy chars from string1 to string1
    sb $t5, 0($s7)

    addi $t1, $t1, -1   #counter of whole string1
    addi $t0, $t0, -1   #counter of the character we want to erise

    addi $s0, $s0, 1    #move to next char
    addi $s7, $s0, 1    #move to next char
    beqz $t0, shift     #if we at char we want erise, we skip it in string 1 and continue
    beqz $t1, print     #if string is finished, print result
j findchar

print:  
    la $a0, str2
    #sub $s7, $s7, $s6  #return to first char of new string
    #addi $t1, $t1, -1
    #sub $s7, $s7, $t6
    la $a0, 0($s7)      #and print reult string
    li $v0, 4
    syscall


end:    li $v0, 10
    syscall
shift:  addi $s0, $s0, 1    #skip erised char in string1
    addi $t1, $t1, -1

    j ret           #continue copy chars from string1 to string2

I see a couple of problems with your code. 我发现您的代码有几个问题。

  • The first is that you don't seem to add any NULL terminator to the copied string, which is likely to result in a lot of garbage being printed when you try to print the string. 首先是您似乎没有在复制的字符串中添加任何NULL终止符,这在尝试打印字符串时可能会导致打印大量垃圾。

  • The second is that you always loop 127 times, but the input string isn't likely to be 127 characters long. 第二个是您总是循环127次,但是输入字符串的长度不可能是127个字符。 You should stop looping when you reach the end of the input string (the NULL terminator). 到达输入字符串(NULL终止符)的末尾时,应停止循环。

  • The third is that your implementation would fail if the user wants to remove the very first character, since your skip check is performed after a character has been copied. 第三点是,如果用户要删除第一个字符,则实现将失败,因为在复制字符后将执行跳过检查。

Then there's also the issue of unnecessarily complex ways of doing things. 还有一个问题是不必要的复杂的做事方式。 I saw a few places in the code where you calculate constant values based on some earlier value, instead of just loading the constant again. 我在代码中看到了一些地方,您可以根据一些较早的值来计算常量值,而不仅仅是再次加载常量。 For example, addiu $s7, $s7, -127 / la $a0, 0($s7) could have been replaced by a simple la $a0, str2 . 例如, addiu $s7, $s7, -127 / la $a0, 0($s7) addiu $s7, $s7, -127 la $a0, 0($s7)可能已被简单的la $a0, str2代替。 This sort of stuff is just going to cause you headaches when your code breaks because it relied on something that no longer is valid because you changed something elsewhere in the code. 当代码中断时,这种东西只会使您头疼,因为它依赖于不再有效的内容,因为您在代码中的其他地方进行了更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM