Mips字符串长度,连接和复制显示是错误的

时间:2014-03-15 20:41:07

标签: mips strcpy strcat spim

我正在编写一个Mips汇编代码,以便在我的计算机组织和汇编类中获得额外的功劳。

我们要取三个字符串(S1, S2, S3)。然后我们将三个字符串连接成另一个字符串(S4 = S1+S2+S3)。我们还复制了这个字符串,以便S6 = S4。我们还获得了连接字符串的长度,使L2 = S4长度。
之后,我们将S3字符串复制到S5。最后,我们获得S1的长度。

然而,我的显示是错误的。代码应该显示'结合的三个字符串是:我喜欢汇编。字符串4的长度是:15。当字符串4被复制到字符串6中时,字符串6是:我喜欢组装。当字符串3被复制到字符串5中时,字符串5是:assembly。第一个字符串的长度为:2'。

而不是得到这个,我的显示器显示'三个字符串组合:我喜欢ssemblyy。字符串4的长度是:268501001.当字符串4被复制到字符串6中时,字符串6是:我喜欢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

`

1 个答案:

答案 0 :(得分:0)

这里有很多错误,所以我想我会解决第一个问题,即取3个字符串并将它们连接起来。

我做的第一件事就是取出.align 4指令。它不需要在那里。您要求编译器与2^4字节边界对齐。也许你的意思是.align 2用于单词对齐,但这仍然是不必要的,因为你存储字符串而不是单词。

接下来,我查看了您的strcatFirst程序。我注意到每个循环都会使两个寄存器前进。一个是包含要复制到的字的地址的寄存器,第二个是包含要复制到的字的地址的寄存器。

我不知道为什么,但我猜这是一个错字导致你在每个循环中从$s0增加到$s1$s2。请注意,sb的目标寄存器应始终为$s0

最后,您的函数printConcat出现问题。首先,有一堆堆栈操作看起来完全没必要,所以我删除了它。接下来,您尝试使用string4打印$s0,忘记自$s0加载后strcatFirst$a的值已更改。

我想指出的一件重要事情是你使用变量违反了MIPS calling convention。您应该使用$s寄存器作为函数的参数 - 而不是.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 寄存器。

以下是解决第1部分的解决方案:

{{1}}