0

I am writing a Mips Assembly code for extra credit in my Computer Organization and Assembly Class.

We are to take three strings(S1, S2, S3). Then we concatenate the three strings into another(S4 = S1+S2+S3). We also copy this string, so that S6 = S4. We also obtain the length of our concatenated string so L2 = S4 length.
After that, we copy our S3 string into S5. Lastly, we obtain the length of S1.

However, my display is wrong. The code is supposed to display 'The three strings combined are: I love assembly. The length of string 4 is: 15. When string 4 is copied into string 6, string 6 is: I love assembly. When string 3 is copied into string 5, string 5 is: assembly. The length of the first string is: 2'.

Instead of getting this, my display shows 'The three strings combined are: I love ssemblyy. The length of string 4 is: 268501001. When string 4 is copied into string 6, string 6 is: I love ssemblyy. When string 3 is copied into string 5, string 5 is: ssemblyy. The length of the first string is: 17'.

Where have I gone wrong in my code to create this display?`

.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

`

Stack Player
  • 1,470
  • 2
  • 18
  • 32
user3408013
  • 1
  • 1
  • 1

1 Answers1

0

There are a lot of things wrong here, so I think I will just address the first problem, which is to take 3 strings and concatenate them.

The first thing I did was take out the .align 4 directive. It doesn't need to be there. You are asking the compiler to align to a 2^4 byte boundary. Perhaps you meant .align 2 for word aligned, but this is still unnecessary as you are storing strings not words.

Next I looked at your strcatFirst procedure. I noticed that each of the loops advances the two registers. One is the register containing the address of the word being copied to, and the second is the register containing the address of the word being copied to.

I'm not sure why, but I'm guessing it's a typo that caused you to increase from $s0 to $s1 to $s2 in each of your loops. Remember that the destination register of sb should always be $s0.

Finally, there was a problem in your function printConcat. Firstly, there was a bunch of stack manipulation that looked completely unneccessary so I removed it. Next you attempt to print string4 by using $s0, forgetting that the value of $s0 has been changed in strcatFirst since it was loaded.

One important thing I want to point out is that your use of variables is violating the MIPS calling convention. You should be using the $a registers as arguments to a function -- not the $s registers.

Below is the solution to part 1 fixed up:

.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
Konrad Lindenbach
  • 4,911
  • 1
  • 26
  • 28