MIPS-如何将一个字符串添加到另一个字符串
MIPS- How to add one string to another
我需要在 MIPS 中编写一个程序来查找两个输入字符串参数的长度。之后程序需要将较短的字符串添加到较大的字符串,计算其长度并打印整个字符串。然后编写一个测试过程的主要功能,以便您完成以下过程:从键盘输入字符串,调用过程并打印新数组屏幕的长度。
我将两个名字存储在不同的寄存器中,但在打印全名之前我需要将它们合并为一个。
代码:
.data
first:.asciiz "First string: \n"
last:.asciiz "Second string: \n"
full:.asciiz "Full string: "
.text
main:
# first string
li $v0, 4 # 4 prints a line
la $a0, first # Print first string text
syscall # Syscall
add $a1, $a1, 254 # Setting String length
li $v0, 8 # 8 will read string
syscall # calls the word
sw $v0, first
move $v0, $t1 # The string is now in $t1
# second string
li $v0, 4 # 4 prints a line
la $a0, last # Print second string text
syscall # Syscall
li $v0, 8 # 8 will read string
syscall # calls the word
sw $v0, last
move $v0, $t2 # The string is now in $t2
# Full string
li $v0, 4 # 4 prints a line
la $a0, full # Print the whole text
syscall
嗯,看来你对 syscall 8
有一些误解。您必须使用输入缓冲区的地址加载$a0,并使用[=35]加载$a1 =]要读取的最大字符数。
在您的代码中,您告诉系统调用输入缓冲区将覆盖 first
的内容,这很好。但是,在这一点上,$v0 是 8,而 sw $v0, first
将在 first
中写入 0x8,因此,在 $a0
。所以你只是丢失了字符串。
这应该有效:
1) 开始为两个输入缓冲区保留 space。这可以按 firstread: .space 254
来完成。对 lastread: .space 254
.
做同样的事情
2) 在$a0中加载firstread
,在$a1中加载253
,\n的space 应该保留。使用 syscall
读取字符串到 firstread 的地址。
3) 在$a0中加载lastread
并保持$a1的值。使用系统调用将字符串读取到 lastread 的地址。
此时,您已读取两个字符串并将其存储在 内存 中。您不知道每个字节的大小,因此您必须遍历它们以计算字节数,直到在每个字节中找到 空字节 (0x0)。剩下的就简单了。您可以轻松地查看字节数,看哪个更大或更小。试试看,如果不成功请告诉我。
您需要提示、去除换行符并计算两个输入字符串的字符串长度。您还应该为输入字符串和组合输出字符串设置单独的字符串缓冲区。
这是一些工作代码:
.data
first: .asciiz "First string: "
last: .asciiz "Second string: "
full: .asciiz "Full string: "
newline: .asciiz "\n"
string1: .space 256 # buffer for first string
string2: .space 256 # buffer for second string
string3: .space 512 # combined output buffer
.text
main:
# prompt and read first string
la $a0,first # prompt string
la $a1,string1 # buffer address
jal prompt
move $s0,$v0 # save string length
# prompt and read second string
la $a0,last # prompt string
la $a1,string2 # buffer address
jal prompt
move $s1,$v0 # save string length
# point to combined string buffer
# NOTE: this gets updated across strcat calls (which is what we _want_)
la $a0,string3
# decide which string is shorter based on lengths
blt $s0,$s1,string1_short
# string 1 is longer -- append to output
la $a1,string1
jal strcat
# string 2 is shorter -- append to output
la $a1,string2
jal strcat
j print_full
string1_short:
# string 2 is longer -- append to output
la $a1,string2
jal strcat
# string 1 is shorter -- append to output
la $a1,string1
jal strcat
# show results
print_full:
# output the prefix message for the full string
li $v0,4
la $a0,full
syscall
# output the combined string
li $v0,4
la $a0,string3
syscall
# finish the line
li $v0,4
la $a0,newline
syscall
li $v0,10
syscall
# prompt -- prompt user for string
#
# RETURNS:
# v0 -- length of string (with newline stripped)
#
# arguments:
# a0 -- address of prompt string
# a1 -- address of string buffer
#
# clobbers:
# v1 -- holds ASCII for newline
prompt:
# output the prompt
li $v0,4 # syscall to print string
syscall
# get string from user
li $v0,8 # syscall for string read
move $a0,$a1 # place to store string
li $a1,256 # maximum length of string
syscall
li $v1,0x0A # ASCII value for newline
move $a1,$a0 # remember start of string
# strip newline and get string length
prompt_nltrim:
lb $v0,0($a0) # get next char in string
addi $a0,$a0,1 # pre-increment by 1 to point to next char
beq $v0,$v1,prompt_nldone # is it newline? if yes, fly
bnez $v0,prompt_nltrim # is it EOS? no, loop
prompt_nldone:
subi $a0,$a0,1 # compensate for pre-increment
sb $zero,0($a0) # zero out the newline
sub $v0,$a0,$a1 # get string length
jr $ra # return
# strcat -- append string
#
# RETURNS:
# a0 -- updated to end of destination
#
# arguments:
# a0 -- pointer to destination buffer
# a1 -- pointer to source buffer
#
# clobbers:
# v0 -- current char
strcat:
lb $v0,0($a1) # get the current char
beqz $v0,strcat_done # is char 0? if yes, done
sb $v0,0($a0) # store the current char
addi $a0,$a0,1 # advance destination pointer
addi $a1,$a1,1 # advance source pointer
j strcat
strcat_done:
sb $zero,0($a0) # add EOS
jr $ra # return
我需要在 MIPS 中编写一个程序来查找两个输入字符串参数的长度。之后程序需要将较短的字符串添加到较大的字符串,计算其长度并打印整个字符串。然后编写一个测试过程的主要功能,以便您完成以下过程:从键盘输入字符串,调用过程并打印新数组屏幕的长度。
我将两个名字存储在不同的寄存器中,但在打印全名之前我需要将它们合并为一个。 代码:
.data first:.asciiz "First string: \n" last:.asciiz "Second string: \n" full:.asciiz "Full string: " .text main: # first string li $v0, 4 # 4 prints a line la $a0, first # Print first string text syscall # Syscall add $a1, $a1, 254 # Setting String length li $v0, 8 # 8 will read string syscall # calls the word sw $v0, first move $v0, $t1 # The string is now in $t1 # second string li $v0, 4 # 4 prints a line la $a0, last # Print second string text syscall # Syscall li $v0, 8 # 8 will read string syscall # calls the word sw $v0, last move $v0, $t2 # The string is now in $t2 # Full string li $v0, 4 # 4 prints a line la $a0, full # Print the whole text syscall
嗯,看来你对 syscall 8
有一些误解。您必须使用输入缓冲区的地址加载$a0,并使用[=35]加载$a1 =]要读取的最大字符数。
在您的代码中,您告诉系统调用输入缓冲区将覆盖 first
的内容,这很好。但是,在这一点上,$v0 是 8,而 sw $v0, first
将在 first
中写入 0x8,因此,在 $a0
。所以你只是丢失了字符串。
这应该有效:
1) 开始为两个输入缓冲区保留 space。这可以按 firstread: .space 254
来完成。对 lastread: .space 254
.
2) 在$a0中加载firstread
,在$a1中加载253
,\n的space 应该保留。使用 syscall
读取字符串到 firstread 的地址。
3) 在$a0中加载lastread
并保持$a1的值。使用系统调用将字符串读取到 lastread 的地址。
此时,您已读取两个字符串并将其存储在 内存 中。您不知道每个字节的大小,因此您必须遍历它们以计算字节数,直到在每个字节中找到 空字节 (0x0)。剩下的就简单了。您可以轻松地查看字节数,看哪个更大或更小。试试看,如果不成功请告诉我。
您需要提示、去除换行符并计算两个输入字符串的字符串长度。您还应该为输入字符串和组合输出字符串设置单独的字符串缓冲区。
这是一些工作代码:
.data
first: .asciiz "First string: "
last: .asciiz "Second string: "
full: .asciiz "Full string: "
newline: .asciiz "\n"
string1: .space 256 # buffer for first string
string2: .space 256 # buffer for second string
string3: .space 512 # combined output buffer
.text
main:
# prompt and read first string
la $a0,first # prompt string
la $a1,string1 # buffer address
jal prompt
move $s0,$v0 # save string length
# prompt and read second string
la $a0,last # prompt string
la $a1,string2 # buffer address
jal prompt
move $s1,$v0 # save string length
# point to combined string buffer
# NOTE: this gets updated across strcat calls (which is what we _want_)
la $a0,string3
# decide which string is shorter based on lengths
blt $s0,$s1,string1_short
# string 1 is longer -- append to output
la $a1,string1
jal strcat
# string 2 is shorter -- append to output
la $a1,string2
jal strcat
j print_full
string1_short:
# string 2 is longer -- append to output
la $a1,string2
jal strcat
# string 1 is shorter -- append to output
la $a1,string1
jal strcat
# show results
print_full:
# output the prefix message for the full string
li $v0,4
la $a0,full
syscall
# output the combined string
li $v0,4
la $a0,string3
syscall
# finish the line
li $v0,4
la $a0,newline
syscall
li $v0,10
syscall
# prompt -- prompt user for string
#
# RETURNS:
# v0 -- length of string (with newline stripped)
#
# arguments:
# a0 -- address of prompt string
# a1 -- address of string buffer
#
# clobbers:
# v1 -- holds ASCII for newline
prompt:
# output the prompt
li $v0,4 # syscall to print string
syscall
# get string from user
li $v0,8 # syscall for string read
move $a0,$a1 # place to store string
li $a1,256 # maximum length of string
syscall
li $v1,0x0A # ASCII value for newline
move $a1,$a0 # remember start of string
# strip newline and get string length
prompt_nltrim:
lb $v0,0($a0) # get next char in string
addi $a0,$a0,1 # pre-increment by 1 to point to next char
beq $v0,$v1,prompt_nldone # is it newline? if yes, fly
bnez $v0,prompt_nltrim # is it EOS? no, loop
prompt_nldone:
subi $a0,$a0,1 # compensate for pre-increment
sb $zero,0($a0) # zero out the newline
sub $v0,$a0,$a1 # get string length
jr $ra # return
# strcat -- append string
#
# RETURNS:
# a0 -- updated to end of destination
#
# arguments:
# a0 -- pointer to destination buffer
# a1 -- pointer to source buffer
#
# clobbers:
# v0 -- current char
strcat:
lb $v0,0($a1) # get the current char
beqz $v0,strcat_done # is char 0? if yes, done
sb $v0,0($a0) # store the current char
addi $a0,$a0,1 # advance destination pointer
addi $a1,$a1,1 # advance source pointer
j strcat
strcat_done:
sb $zero,0($a0) # add EOS
jr $ra # return