在MIPS中空终止字符串?

时间:2015-10-09 03:58:01

标签: assembly mips

我正在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

2 个答案:

答案 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并不是必需的,因为循环始终是下一条具有失败的下一条指令。