我正在MIPS中编写strncpy
,但是我遇到了无效的字符串终止问题。如果我自己没有空终止它,字符串会继续。我试过了sb $__ 0($0)
,但这似乎不起作用......
$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
答案 0 :(得分:0)
为了使这篇文章完整,我将参加上面提到的dublicate poast的外套并完成它:
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
答案 1 :(得分:0)
以空值终止字符串是将0
字节写入字符串的终止偏移量的问题。
您的尝试lb $a0 0(0)
加载一个字节,但是由于空终止需要写入,因此您可能是指sb
。将0(0)
用作地址没有太大意义,$a0
也不用作源寄存器,因为它包含一个地址。
正确的版本是sb $zero ($a0)
。这会将0
字节写入到$a0
的偏移量处,该偏移量可以方便地指向字符串的尾部,这可能是由于在源字符串中遇到了空终止符或计数期满,以先到者为准。>
这是一个最小的完整示例:
.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
关于您的代码的其他说明:
sb $a0 0($a1)
不正确;尝试将地址存储为字节(改为使用$t2
),而$a1
是源地址,而不是目标地址。beq $a2 $0 done # if num chars to copy is 0, return.
似乎没有必要。循环终止条件已经对此进行了检查。beq $t2 $0 done
可以简化为beqz $t2 done
。j cpyLoop
并不是必需的,因为循环始终是下一条具有失败的下一条指令。