Assembly 在MIPS中终止字符串是否为Null?
我正在MIPS中编写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:
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
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很少是个好主意。