Assembly 在MIPS中终止字符串是否为Null?

Assembly 在MIPS中终止字符串是否为Null?,assembly,mips,Assembly,Mips,我正在MIPS中编写strncpy,但是在终止字符串时遇到了null问题。如果我自己不使用null终止它,字符串就会继续。我试过sb$\uu0($0),但似乎不起作用 $a0=指向目标数组的指针 $a1=源字符串 $a2=要复制的字符数 strncpy: add $t1 $zero $zero #counter beq $a2 $0 done # if num chars to copy is 0, return. j cpyLoop cpyLoop:

我正在MIPS中编写
strncpy
,但是在终止字符串时遇到了null问题。如果我自己不使用null终止它,字符串就会继续。我试过
sb$\uu0($0)
,但似乎不起作用

$a0=指向目标数组的指针

$a1=源字符串

$a2=要复制的字符数

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

为了完成这篇文章,我将从上面提到的dublicate poast中提取一部分coat并完成它:

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

为了完成这篇文章,我将从上面提到的dublicate poast中提取一部分coat并完成它:

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

Null终止字符串就是将
0
字节写入字符串中的终止偏移量

您的尝试,
lb$a0(0)
加载一个字节,但由于null终止需要写入,您可能是指
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
.data
dst:.空间12
src:.asciiz“你好,世界”
.文本
主要内容:
la$a0 dst#目的地字符串
la$a1 src#源字符串
li$a2 5#要复制的字符数
日本航空公司
#打印目标字符串
洛杉矶时间0美元
李$V04
系统调用
#打印“\n”
李$A010
李$v0 11
系统调用
李:10美元
系统调用
strncpy:
li$T00指数
strncpy_循环:
#而计数器

关于代码的其他备注:

  • sb$a0($a1)
    不正确;它试图将地址存储为字节(改为使用
    $t2
    ),而
    $a1
    是源地址,而不是目标地址
  • 前提条件
    beq$a2$0 done#如果要复制的字符数为0,则返回。
    似乎没有必要。循环终止条件已对此进行检查
  • beq$t2$0完成
    可以简化为
    beqz$t2完成
  • 第一个
    j cpyLoop
    是不必要的,因为循环是下一条具有故障诊断功能的指令

Null终止字符串就是将
0
字节写入字符串中的终止偏移量

您的尝试,
lb$a0(0)
加载一个字节,但由于null终止需要写入,您可能是指
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
.data
dst:.空间12
src:.asciiz“你好,世界”
.文本
主要内容:
la$a0 dst#目的地字符串
la$a1 src#源字符串
li$a2 5#要复制的字符数
日本航空公司
#打印目标字符串
洛杉矶时间0美元
李$V04
系统调用
#打印“\n”
李$A010
李$v0 11
系统调用
李:10美元
系统调用
strncpy:
li$T00指数
strncpy_循环:
#而计数器

关于代码的其他备注:

  • sb$a0($a1)
    不正确;它试图将地址存储为字节(改为使用
    $t2
    ),而
    $a1
    是源地址,而不是目标地址
  • 前提条件
    beq$a2$0 done#如果要复制的字符数为0,则返回。
    似乎没有必要。循环终止条件已对此进行检查
  • beq$t2$0完成
    可以简化为
    beqz$t2完成
  • 第一个
    j cpyLoop
    是不必要的,因为循环是下一条具有故障诊断功能的指令
这个问题与“我已经尝试了
sb$\uu0($0)
”相同。尝试写入地址0很少是个好主意。这与“我已经尝试了
sb$\uuu0($0)
”相同。尝试写入地址0很少是个好主意。