MIPS-如何将一个字符串添加到另一个字符串

时间:2016-04-23 20:14:01

标签: assembly mips

我需要在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  

2 个答案:

答案 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