0

私は、コンピューター組織とアセンブリ クラスで追加のクレジットを得るために、Mips アセンブリ コードを書いています。

3 つの文字列 ( S1, S2, S3) を取ります。次に、3 つの文字列を別の ( S4 = S1+S2+S3) に連結します。この文字列もコピーするので、S6 = S4. また、連結された文字列の長さを取得しますL2 = S4
その後、S3文字列を にコピーしますS5。最後に、 の長さを取得しS1ます。

しかし、私の表示は間違っています。このコードは、「結合された 3 つの文字列は次のとおりです: I love assembly. 弦 4 の長さは 15 です。弦 4 を弦 6 にコピーすると、弦 6 は次のようになります。文字列 3 を文字列 5 にコピーすると、文字列 5 はアセンブリになります。最初の文字列の長さは 2' です。

これを取得する代わりに、私のディスプレイには「結合された 3 つの文字列は次のとおりです。私は ssemblyy が大好きです。文字列 4 の長さは 268501001 です。文字列 4 を文字列 6 にコピーすると、文字列 6 は次のようになります。I love ssemblyy. 文字列 3 を文字列 5 にコピーすると、文字列 5 は ssemblyy になります。最初のストリングの長さは 17 フィートです。

この表示を作成するコードのどこが間違っていますか?`

.data
.align 4
S1: .asciiz "I "
S2: .asciiz "love "
S3: .asciiz "assembly"
string1: .asciiz "The first string is:\n"
string2: .asciiz "\nThe second string is:\n"
string3: .asciiz "\nThe third string is:\n"
string4: .space 16
string5: .space 9
string6: .space 16
S4: .asciiz "\nThe three strings combined are: "
S5: .asciiz "\nWhen string 3 is copied into string 5, string 5 is: "
S6: .asciiz "\nWhen string 4 is copied into string 6, string 6 is: "
L1: .asciiz "\nThe length of the first string is: "
L2: .asciiz "\nThe length of string 4 is: "
.text
main:
    #display all three strings first
    li $v0, 4
    la $a0, string1
    syscall
    la $a0, S1
    syscall
    la $a0, string2
    syscall
    la $a0, S2
    syscall
    la $a0, string3
    syscall
    la $a0, S3
    syscall
    #display the three string when concatenated, as well as copied into S6, and their length
    la $s0, string4
    la $s1, S1
    la $s2, S2
    la $s3, S3
    jal strcatFirst
    jal printConcat
    addi $a2, $a1, 0
    addi $v1, $v0, 0
    addi $v0, $0, 11
    la $s0, S4
    syscall
    jal printConcatCopy
    addi $s2, $s1, 0
    addi $v1, $v0, 0
    addi $v0, $0, 11
    la $s0, S6
    syscall
    jal printConcatLength
    addi $a2, $a1, 0
    addi $v1, $v0, 0
    addi $v0, $0, 11
    la $s0, L2
    syscall
    #display string 5 when string 3 is copied into it
    la $s1, string5
    la $s2, S3
    jal strcpy    
    jal print2
    addi $s2, $s1, 0
    addi $v1, $v0, 0
    addi $v0, $0, 11
    la $s0, S5
    syscall
    #display length of string 1
    la $a0, S1 #load address of string
    jal strlen #call string length procedure
    move $a0, $v0
    jal print4
    addi $a1, $a0, 0 #move address of string to $a1
    addi $v1, $v0, 0 #move length of string to $v1
    addi $v0, $0, 11 #syscall code for message
    la $a0, L1 #address of message
    syscall
    li $v0, 10
    syscall

strcatFirst:
    lb $t0, ($s1)
    beqz $t0, strcatSecond
    sb $t0, ($s0)
    addi $s1, $s1, 1
    addi $s0, $s0, 1
    j strcatFirst

strcatSecond:
    lb $t0,($s2)
    beqz $t0, strcatThird
    sb $t0, ($s1)
    addi $s2, $s2, 1
    addi $s1, $s1, 1
    j strcatSecond

strcatThird:
    lb $t0, ($s3)
    beqz $t0, endStrcat
    sb $t0, ($s2)
    addi $s3, $s3, 1
    addi $s2, $s2, 1
    j strcatThird

endStrcat:
    jr $ra
printConcat:
    addi $sp, $sp, -12
    sw $fp, 8($sp)
    addi $fp, $sp, 16
    sw $ra, 0($fp)
    sw $s0, -4($fp)
    move $s0, $a0 # store the argument in a save register
    li $v0, 4
    la $a0, S4
    syscall
    li $v0, 4
    move $a0, $s0 # retrieve the argument from $s0
    syscall
    lw $s0, -4($fp)
    lw $ra, 0($fp)
    lw $fp, 8($sp)
    addi $sp, $sp, 12
    jr $ra

strcpy:
    lbu $t0, 0($s2) #load a byte from source string
    beqz $t0, cpyExit #stop when null is copied
    sb $t0, 0($s1) #store byte in destination string
    addi $s2, $s2, 1 #increment both addresses
    addi $s1, $s1, 1

    j strcpy


cpyExit:
    jr $ra

print2:
    addi $sp, $sp, -12
    sw $fp, 8($sp)
    addi $fp, $sp, 16
    sw $ra, 0($fp)
    sw $s0, -4($fp)
    move $s0, $a0 # store the argument in a save register
    li $v0, 4
    la $a0, S5
    syscall
    li $v0, 4
    move $a0, $s0 # retrieve the argument from $s0
    syscall
    lw $s0, -4($fp)
    lw $ra, 0($fp)
    lw $fp, 8($sp)
    addi $sp, $sp, 12
    jr $ra

printConcatCopy:
    addi $sp, $sp, -12
    sw $fp, 8($sp)
    addi $fp, $sp, 16
    sw $ra, 0($fp)
    sw $s0, -4($fp)
    move $s0, $a0 # store the argument in a save register
    li $v0, 4
    la $a0, S6
    syscall
    li $v0, 4
    move $a0, $s0 # retrieve the argument from $s0
    syscall
    lw $s0, -4($fp)
    lw $ra, 0($fp)
    lw $fp, 8($sp)
    addi $sp, $sp, 12
    jr $ra

printConcatLength:
    addi $sp, $sp, -12
    sw $fp, 8($sp)
    addi $fp, $sp, 16
    sw $ra, 0($fp)
    sw $s0, -4($fp)
    move $s0, $a0 # store the argument in a save register
    li $v0, 4
    la $a0, L2
    syscall
    li $v0, 1
    move $a0, $s0 # retrieve the argument from $s0
    syscall
    lw $s0, -4($fp)
    lw $ra, 0($fp)
    lw $fp, 8($sp)
    addi $sp, $sp, 12
    jr $ra                
 strlen:
    move $t0, $zero #initialize count to start with 0 for first character
    j strlen.test
strlen.loop:
    addi $a0, $a0, 1 #load increment string pointer
    addi $t0, $t0, 1 #increment count
strlen.test:
    lb $t1, 0($a0) #load the next character to t0
    bnez $t1, strlen.loop #end loop if null character is reached
    move $v0, $t0
    jr $ra
print4:
    addi $sp, $sp, -12
    sw $fp, 8($sp)
    addi $fp, $sp, 16
    sw $ra, 0($fp)
    sw $s0, -4($fp)
    move $s0, $a0 # store the argument in a save register
    li $v0, 4
    la $a0, L1
    syscall
    li $v0, 1
    move $a0, $s0 # retrieve the argument from $s0
    syscall
    lw $s0, -4($fp)
    lw $ra, 0($fp)
    lw $fp, 8($sp)
    addi $sp, $sp, 12
    jr $ra

`

4

1 に答える 1

0

ここには多くの問題があるので、最初の問題、つまり 3 つの文字列を取得してそれらを連結することだけに対処すると思います。

.align 4私が最初にしたことは、ディレクティブを取り出すことでした。そこにある必要はありません。コンパイラに2^4バイト境界に合わせるように要求しています。おそらく.align 2、単語を揃えるつもりでしたが、単語ではなく文字列を格納しているため、これはまだ不要です。

次に、私はあなたのstrcatFirst手順を見ました。各ループが 2 つのレジスタを進めることに気付きました。1 つはコピー先のワードのアドレスを含むレジスターで、2 つ目はコピー先のワードのアドレスを含むレジスターです。

理由はわかりませんが、各ループで$s0to$s1を増加させたのはタイプミスだと思います。$s2の宛先レジスタはsb常にである必要があることに注意してください$s0

最後に、関数に問題がありましたprintConcat。まず、完全に不要に見えるスタック操作がたくさんあったので、それを削除しました。次に、ロード後にの値が変更されたことを忘れて、string4を使用して印刷しようとしました。$s0$s0strcatFirst

指摘しておきたい重要な点の 1 つは、変数の使用がMIPS 呼び出し規則に違反していることです。$aレジスタではなく、関数への引数としてレジスタを使用する必要があります$s

以下は、修正されたパート 1 の解決策です。

.data
S1: .asciiz "I "
S2: .asciiz "love "
S3: .asciiz "assembly"
string1: .asciiz "The first string is: "
string2: .asciiz "\nThe second string is: "
string3: .asciiz "\nThe third string is: "
string4: .space 16
S4: .asciiz "\nThe three strings combined are: "

.text
main:
    #display all three strings first
    li $v0, 4
    la $a0, string1
    syscall
    la $a0, S1
    syscall
    la $a0, string2
    syscall
    la $a0, S2
    syscall
    la $a0, string3
    syscall
    la $a0, S3
    syscall

    #concat
    la $a0, string4
    la $a1, S1
    la $a2, S2
    la $a3, S3
    jal strcatFirst

    #print
    jal printConcat

    #exit
    li $v0, 10
    syscall

strcatFirst:
        lb $t0, ($a1)
        beqz $t0, strcatSecond
        sb $t0, ($a0)
        addi $a1, $a1, 1
        addi $a0, $a0, 1
    j strcatFirst

    strcatSecond:
        lb $t0,($a2)
        beqz $t0, strcatThird
        sb $t0, ($a0)
        addi $a2, $a2, 1
        addi $a0, $a0, 1
        j strcatSecond

    strcatThird:
        lb $t0, ($a3)
        beqz $t0, endStrcat
        sb $t0, ($a0)
        addi $a3, $a3, 1
        addi $a0, $a0, 1
        j strcatThird

    endStrcat:
        jr $ra

printConcat:

    #print label
    li $v0, 4
    la $a0, S4
    syscall

    #print string4
    li $v0, 4
    la $a0, string4
    syscall

    jr $ra
于 2014-03-16T03:08:23.197 に答える