最初にいくつかの注意事項:
- あなたは持ってい
.text
て.data
混同しています
文字列の最後に改行を追加すると、表示が少し見やすくなります。
String: .asciiz "Hello, world.\n"
文字列の長さに 13 を使用すると仮定すると、float の代わりに整数を使用する必要があります。
x: .word 13
さて、問題に。これを行うには 2 つの方法があります。1) 文字列をその場で回転させ、syscall 4
毎回呼び出すか、2) 文字列をそのままにして、一度に 1 文字ずつ出力し、代わりにインデックスを操作して回転効果を実現します。方法 1 を選択したので、それを使用します。
疑似コードを書くことから始めます。$a0
に格納されている文字列を 1 文字左に回転させるサブルーチンが必要です。すぐに、文字列内の各文字を反復するある種のループについて考える必要があります。
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
ので、当然のこととしましょう。少なくとも 1 つの一時レジスタが必要です。すでに$t0
forを使用しているので、最初の文字を保持するためにx
使用しましょう。$t1
MoveString:
lb $t1, String
インデックスレジスタも必要なので、それを使いましょう$t2
。ゼロに初期化します。
li $t2, 0
アドレス レジスタを文字ごとに 1 つずつインクリメントするだけでよいのですが、$a0
めちゃくちゃになるので上書きはしたくありませんPrintString
。$a1
それをfor ループにコピーしましょう:
move $a1, $a0
最後に、文字列の長さを知る必要があるため、 の別のコピーをにロードしましょx
う$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.