问题
I'm writing strncpy
in MIPS, but I'm having trouble null-terminating the string. If i do not null-terminate it myself, the string goes on and on. I have tried sb $__ 0($0)
but that does not seem to work...
$a0 = pointer to destination array
$a1 = source string
$a2 = number of characters to copy
strncpy:
add $t1 $zero $zero #counter
beq $a2 $0 done # if num chars to copy is 0, return.
j cpyLoop
cpyLoop:
beq $t1 $a2 done # if counter == num to copy, end
lb $t2 0($a1) # load the character
beq $t2 $0 done #if we reach the null char, end
sb $a0 0($a1)
addi $a0 $a0 1 #increment the pointer in dest array
addi $a1 $a1 1 #increment the pointer in source array
addi $t1 $t1 1 #increment the counter
j cpyLoop
done:
lb $a0 0(0)
move $v0 $a0
jr $ra
回答1:
to make this post complete i will take part of coat from the dublicate poast mentioned above and complete it:
addi $a3 $a0 0
strncpy:
beqz $a2, out
lb $t0, 0($a1) #load byte
beqz $t0 out
subiu $a2, $a2, 1
sb $t0, 0($a0)
addiu $a0, $a0, 1
addiu $a1, $a1, 1
j strncpy
out:
move $a0 $a3
move $v0 $a0
jr $ra
回答2:
Null-terminating a string is a matter of writing a 0
byte to the terminating offset in the string.
Your attempt, lb $a0 0(0)
loads a byte, but because null termination entails writing, you probably meant sb
. Using 0(0)
as the address doesn't make much sense, nor does $a0
as the source register since it contains an address.
The correct version is sb $zero ($a0)
. This writes a 0
byte to the offset at $a0
which conveniently points to the tail of the string, either due to encountering the null terminator in the source string or the count expiring, whichever is first.
Here's a minimal, complete example:
.data
dst: .space 12
src: .asciiz "hello world"
.text
main:
la $a0 dst # destination string
la $a1 src # source string
li $a2 5 # number of chars to copy
jal strncpy
# print the destination string
la $a0 dst
li $v0 4
syscall
# print '\n'
li $a0 10
li $v0 11
syscall
li $v0 10
syscall
strncpy:
li $t0 0 # index
strncpy_loop:
# while counter < chars to copy || src[i] != '\0'
beq $t0 $a2 strncpy_done
lb $t1 ($a1) # load src[i]
beqz $t1 strncpy_done
sb $t1 ($a0) # dst[i] = src[i]
addi $t0 $t0 1 # i++
addi $a0 $a0 1 # dst++
addi $a1 $a1 1 # src++
b strncpy_loop
strncpy_done:
sb $zero ($a0) # dst[i] = '\0' null terminate dst
move $v0 $a0
jr $ra
Additional remarks regarding your code:
sb $a0 0($a1)
is incorrect; it's attempting to store an address as a byte (use$t2
instead) and$a1
is the source address, not the destination address.- The precondition
beq $a2 $0 done # if num chars to copy is 0, return.
doesn't appear necessary. The loop termination conditional already checks this. beq $t2 $0 done
can be simplified tobeqz $t2 done
.- The first
j cpyLoop
isn't necessary since the loop is the next instruction with fallthrough anyway.
来源:https://stackoverflow.com/questions/33029678/null-terminating-a-string-in-mips