首先注意几点:
- 你有
.text
并且.data
混淆了
继续在字符串末尾添加一个换行符,它会使显示更好一些:
String: .asciiz "Hello, world.\n"
假设 13 用于字符串的长度,您应该使用整数而不是浮点数:
x: .word 13
现在,进入问题。有两种方法可以做到这一点:1)就地旋转字符串并syscall 4
每次调用,或2)保持字符串原样并一次打印一个字母,而不是使用索引来实现旋转效果。您选择了方法 1,所以让我们开始吧。
首先编写一些伪代码。您需要一个子程序,它将存储的字符串$a0
向左旋转一个字母。立即,您应该考虑某种循环遍历字符串中的每个字母:
for int index from 0 to 12
copy letter from (index + 1) to index
但是等等:第一个字母会发生什么?它会被破坏。当我们到达终点时会发生什么?我们将把边界之外的东西复制String
到最后一个字母槽。因此,让我们通过将第一个字母存储到临时寄存器来解决它:
temp = letter[0]
for int index from 0 to 11
copy letter from (index + 1) to index
letter[12] = temp
这样更好;应该这样做。下一个问题:我们如何在 MIPS 中做到这一点?
我们知道$a0
它将保存字符串的地址,所以让我们认为这是理所当然的。我们至少需要一个临时寄存器——因为我们已经在使用$t0
for x
,让我们用它$t1
来保存第一个字母:
MoveString:
lb $t1, String
我们还需要一个索引寄存器,所以让我们使用$t2
它。将其初始化为零:
li $t2, 0
为每个字母增加一次地址寄存器会很好,但我们不想破坏$a0
,因为它会搞砸PrintString
。所以让我们将它复制到$a1
我们的循环中:
move $a1, $a0
最后,我们需要知道字符串有多长,所以让我们加载另一个副本x
into $t3
:
lb $t3, x
sub $t3, $t3, 1 ; We're only iterating over the first 12 letters,
; since the last letter is done manually with temp
现在我们可以开始循环了。我们需要将字母(只是一个字节)从复制$a1 + 1
到$a1
:
MoveStringLoop:
lb $t4, 1($a1) ; Load the letter from (address + 1)
sb $t4, 0($a1) ; Store it to (address)
add $a1, $a1, 1 ; Increment our address
add $t2, $t2, 1 ; Increment our index
blt $t2, $t3, MoveStringLoop ; Loop again if index < (length - 1)
sb $t1, 0($a1) ; Copy the temp letter to the end of the string
应该是这样的。之后,我们可以递减x
并返回PrintString
:
sub $t0, $t0, 1
b PrintString
无论如何,这都不是最佳解决方案。我确信一个真正的编译器和一些更好的编码可以用一半的指令完成工作。但是由于您正在学习如何编写程序集,所以暂时不要担心微优化。这是最终代码及其输出:
.data
String: .asciiz "Hello, world.\n"
x: .word 13
.text
Main: lw $t0,x
jal PrintString
li $v0, 10
syscall
PrintString: la $a0,String
li $v0,4
syscall
bgtz $t0, MoveString
jr $ra
MoveString:
lb $t1, String
li $t2, 0
move $a1, $a0
lb $t3, x
sub $t3, $t3, 1
MoveStringLoop:
lb $t4, 1($a1)
sb $t4, 0($a1)
add $a1, $a1, 1
add $t2, $t2, 1
blt $t2, $t3, MoveStringLoop
sb $t1, 0($a1)
sub $t0, $t0, 1
b PrintString
输出:
Hello, world.
ello, world.H
llo, world.He
lo, world.Hel
o, world.Hell
, world.Hello
world.Hello,
world.Hello,
orld.Hello, w
rld.Hello, wo
ld.Hello, wor
d.Hello, worl
.Hello, world
Hello, world.