我需要在MIPS中编写一个程序,它将找到两个输入字符串参数的长度。之后,程序需要将较短的字符串添加到较大的字符串,计算其长度并打印整个字符串。然后编写一个将测试过程的main函数,以便完成这些过程:从键盘输入字符串,调用过程并打印新数组屏幕的长度。
我将这两个名字存储在不同的寄存器中,但在打印全名之前我需要将它们合并为一个。 代码:
.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
答案 0 :(得分:1)
好吧,你似乎对syscall 8
有一些误解。您必须使用输入缓冲区地址加载 $ a0 ,并使用 $ a1 加载要读取的最大字符数
在你的代码中,你告诉系统调用输入缓冲区将覆盖first
的内容,这很好。但是,此时 $ v0 8 ,而sw $v0, first
将在first
中写入0x8,因此在$a0
中。所以你只是丢了你的字符串。
这应该有效:
1)开始为两个输入缓冲区保留空间。这可以firstread: .space 254
完成。对lastread: .space 254
执行相同的操作。
2)在 $ a0 中加载firstread
,在 $ a1 中加载253
,\ n的空格应保留。使用syscall
将字符串读取到firstread的地址。
3)在 $ a0 中加载lastread
并保持 $ a1 的值。使用系统调用将字符串读取到lastread的地址。
此时,您已将两个字符串加入并存储在内存中。你不知道每个的大小,所以你必须迭代它们计算字节数,直到你在每个字节中找到空字节(0x0)。其余的很容易。您可以轻松地查看字节数的大小。尝试这样做,如果你没有成功,请告诉我。
答案 1 :(得分:1)
您需要提示,删除换行符,并计算两个输入字符串的字符串长度。您还应该为输入字符串和组合输出字符串分别使用字符串缓冲区。
这是一些有效的代码:
.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