Can't copy a string from one destination to another in mips?

0

I seem to be having some trouble copying a string given by the user from one destination to another. In my code, I get the string from the user, count how many characters are in that string, and then I try to copy it from one place to another. However, it's not working, and it keeps giving me a

Exception occurred at PC=0x00400110
  Bad address in data/stack read: 0x0000006f
  Exception 7  [Bad data address]  occurred and ignored
Memory address out of bounds

error. Here is my code:

.data

    prompt1: .asciiz "Please enter a string> "
    prompt2: .asciiz "The length of the string "
    prompt3: .asciiz "is: "
    string: .space 255
    newstring: .space 255
    nl: .asciiz "\n"

.text

main:

    li $v0, 4
    la $a0, prompt1
    syscall #print the first prompt

    la $a0, string
    li $a1, 255
    li $v0, 8
    syscall #get the string and put it in "array"

    la $a0, string
    li $a1, 255
    addi $s0, $s0, 0
    jal strlen #jump to strlen

    move $t0, $v0 #move whatever strlen got and put in t0
    li $v0, 4
    la $a0, prompt2
    syscall #print prompt2

    li $v0, 4
    la $a0, string
    syscall #print array

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

    li $v0, 1
 move $a0, $t0
    syscall #print number of characters

    li $v0, 4
    la $a0, nl
    syscall #new line!

    li $v0, 4
    la $a0, nl
    syscall #againnnn!

    la $a0, newstring
    la $a1, string
    move $a2, $t0
    jal strncpy


    move $a0, $v0
    li $v0, 4
    syscall

j exit


strlen:
    lb   $s1, 0($a0)     #load next byte
    beqz $s1, firfin     #if byte is '\0', go to firfin
    addi $s0, $s0, 1     #increments character count
    addi $a0, $a0, 1     #move on to next byte
    j    strlen          #jump back and keep going

firfin:
    addi $v0, $s0, -1 #return number of chars - 1 to account for \n
    li $s0, 0 #clean up
    li $s1, 0 #sweepy sweepy
    jr   $ra

strncpy:
    lb   $s1, 0($a1)      #load next byte
    bge  $s0, $a2, secfin #if bigger than string length, jump to secfin
    sb   $a0, 0($s1)
    addi $s0, $s0, 1
    addi $a1, $a1, 1
    j strncpy
secfin:
    move $v0, $a0
    li   $s2, 0
    li   $s1, 0
    li   $s0, 0
    jr   $ra

exit:
    li $v0, 10
    syscall
assembly
mips
asked on Stack Overflow Mar 20, 2014 by user2751164

1 Answer

4

Multiple problems in strncpy:

  1. You don't zero $s0 before you start to use it
  2. You load a byte before you test for end of string
  3. You store $a0 into 0($s1) instead of storing $s1 into 0($a0)
  4. You don't increment $a0
  5. You don't follow the calling convention, by modifying s registers
  6. You have coded memcpy, not strncpy

Learn to use a debugger/simulator to step through your code and see where it goes wrong.

answered on Stack Overflow Mar 20, 2014 by Jester

User contributions licensed under CC BY-SA 3.0