如何在 MIPS 中修改和打印字符串?
How to modify and print a string in MIPS?
我正在处理 MIPS 中的作业。我想打印没有小数点的存储字符串,即 110.11 的输出应该是 11011 。
我认为我的代码正在做它应该做的事情,但它没有显示任何输出。我调试了一下,结果发现addi语句一直在删除字符串的第一个元素,所以最后什么都没有了。
.data
string: .asciiz "110.11"
.text
.globl main
.ent main
main:
la $t1,string
li $t5,46 #ascii code of .=46
LOOP:
lb $t0,($t1)
beq $t0,$t5,SKIP #skip point if found
beq $t0, $zero, exit
sb $t0,($t1)
addi $t1, $t1, 1 #i++
j LOOP
SKIP:
addi $t1, $t1, 1
j LOOP
exit:
li $v0,4
move $a0,$t1
syscall
li $v0,10
syscall
jr $ra
.end main
有没有办法在不删除其元素并将修改后的字符串作为输出的情况下向前移动字符串?如有任何帮助,我们将不胜感激!
你的代码显然没有做它应该做的事情,因为那样你就不会在这里问这个问题了。
你的代码基本上做的是
while (*string) {
if (*string != '.')
*string = *string;
string++;
}
syscall (string);
所以您不仅没有删除点,而且打印了空字符串,或者更准确地说,打印了字符串的和处的终止零字节。
你说"it turns out that the addi
statement just keeps removing the first element of the string so there's nothing left in the end"。似乎缺乏理解该语句的作用以及它与零终止字符串的关系。此循环中的 addi
会将指针前进到字符串的末尾,因为它就是此循环的作用。递增指针意味着指针现在指向第二个字节,因此您将获得从下一个字节开始的字符串。内存本身没有被修改。
你可以尝试这样的事情。它假定您将汇编程序配置为按照写入的顺序执行语句,换句话说,重新排序语句,以便 t1
的添加将进入分支后的插槽。
main:
la $t1,string
move $t2,$t1
move $t3,$t1 # t1 = t2 = t3 = string
li $t5,46 #ascii code of .=46
LOOP:
lb $t0,($t1)
addi $t1, $t1, 1 #t1++
beq $t0,$t5,SKIP #skip point if found
sb $t0,($t2)
addi $t2, $t2, 1 #t2++
SKIP:
bneq $t0, $zero, LOOP # exit on end of string
li $v0,4
move $a0,$t3
syscall
li $v0,10
syscall
jr $ra
在 C 中,这将是
t1 = t2 = t3 = string;
do {
t0 = *t1++;
if (t0 != '.')
*t2++ = t0;
} while (t0 != 0);
syscall (t3);
我正在处理 MIPS 中的作业。我想打印没有小数点的存储字符串,即 110.11 的输出应该是 11011 。
我认为我的代码正在做它应该做的事情,但它没有显示任何输出。我调试了一下,结果发现addi语句一直在删除字符串的第一个元素,所以最后什么都没有了。
.data
string: .asciiz "110.11"
.text
.globl main
.ent main
main:
la $t1,string
li $t5,46 #ascii code of .=46
LOOP:
lb $t0,($t1)
beq $t0,$t5,SKIP #skip point if found
beq $t0, $zero, exit
sb $t0,($t1)
addi $t1, $t1, 1 #i++
j LOOP
SKIP:
addi $t1, $t1, 1
j LOOP
exit:
li $v0,4
move $a0,$t1
syscall
li $v0,10
syscall
jr $ra
.end main
有没有办法在不删除其元素并将修改后的字符串作为输出的情况下向前移动字符串?如有任何帮助,我们将不胜感激!
你的代码显然没有做它应该做的事情,因为那样你就不会在这里问这个问题了。
你的代码基本上做的是
while (*string) {
if (*string != '.')
*string = *string;
string++;
}
syscall (string);
所以您不仅没有删除点,而且打印了空字符串,或者更准确地说,打印了字符串的和处的终止零字节。
你说"it turns out that the addi
statement just keeps removing the first element of the string so there's nothing left in the end"。似乎缺乏理解该语句的作用以及它与零终止字符串的关系。此循环中的 addi
会将指针前进到字符串的末尾,因为它就是此循环的作用。递增指针意味着指针现在指向第二个字节,因此您将获得从下一个字节开始的字符串。内存本身没有被修改。
你可以尝试这样的事情。它假定您将汇编程序配置为按照写入的顺序执行语句,换句话说,重新排序语句,以便 t1
的添加将进入分支后的插槽。
main:
la $t1,string
move $t2,$t1
move $t3,$t1 # t1 = t2 = t3 = string
li $t5,46 #ascii code of .=46
LOOP:
lb $t0,($t1)
addi $t1, $t1, 1 #t1++
beq $t0,$t5,SKIP #skip point if found
sb $t0,($t2)
addi $t2, $t2, 1 #t2++
SKIP:
bneq $t0, $zero, LOOP # exit on end of string
li $v0,4
move $a0,$t3
syscall
li $v0,10
syscall
jr $ra
在 C 中,这将是
t1 = t2 = t3 = string;
do {
t0 = *t1++;
if (t0 != '.')
*t2++ = t0;
} while (t0 != 0);
syscall (t3);