在 MIPS 中空终止一个字符串?

Null-terminating a string in MIPS?

我正在用 MIPS 编写 strncpy,但我无法以 null 终止字符串。如果我自己不以 null 终止它,那么字符串会一直持续下去。我试过 sb $__ 0([=12=]) 但这似乎不起作用...

$a0 = pointer to destination array
$a1 = source string
$a2 = number of characters to copy

strncpy: 
    add $t1 $zero $zero  #counter 
    beq $a2 [=10=] 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 [=10=] 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

为了完成这个 post 我将从上面提到的重复帖子中取出一部分外套并完成它:

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

以空值终止字符串是将 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] != '[=10=]'
    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] = '[=10=]' null terminate dst
    move $v0 $a0
    jr $ra

关于您的代码的补充说明:

  • sb $a0 0($a1)不正确;它试图将地址存储为字节(改为使用 $t2)并且 $a1 是源地址,而不是目标地址。
  • 前提条件 beq $a2 [=22=] done # if num chars to copy is 0, return. 似乎没有必要。循环终止条件已经检查了这一点。
  • beq $t2 [=23=] done可以简化为beqz $t2 done.
  • 第一个 j cpyLoop 不是必需的,因为无论如何循环都是下一条带有 fallthrough 的指令。