【问题标题】:MIPS- How to add one string to anotherMIPS-如何将一个字符串添加到另一个
【发布时间】:2016-08-17 09:16:46
【问题描述】:

我需要在 MIPS 中编写一个过程来查找两个输入字符串参数的长度。之后程序需要将较短的字符串添加到较大的字符串中,计算其长度并打印整个字符串。然后编写一个测试程序的主函数,以便您完成这些过程:从键盘输入字符串,调用程序并打印新数组屏幕的长度。

我将这两个名称存储在单独的寄存器中,但在打印出全名之前,我需要将它们合并为一个。 代码:

。数据 first:.asciiz "第一个字符串:\n" last:.asciiz "第二个字符串:\n" full:.asciiz "完整字符串:" 。文本 主要的: # 第一个字符串 li $v0, 4 # 4 打印一行 la $a0, first # 打印第一个字符串文本 系统调用#系统调用 add $a1, $a1, 254 # 设置字符串长度 li $v0, 8 # 8 将读取字符串 syscall # 调用这个词 sw $v0, 首先 move $v0, $t1 # 字符串现在在 $t1 # 第二个字符串 li $v0, 4 # 4 打印一行 la $a0, last # 打印第二个字符串文本 系统调用#系统调用 li $v0, 8 # 8 将读取字符串 syscall # 调用这个词 sw $v0, 最后 move $v0, $t2 # 字符串现在在 $t2 中 # 完整字符串 li $v0, 4 # 4 打印一行 la $a0, full # 打印整个文本 系统调用

【问题讨论】:

  • 你不应该在这里寻求答案。向我们展示您迄今为止所做的工作,我们会为您提供帮助。
  • 我已经添加了代码...对不起,我是这个论坛的新手...谢谢
  • 你明白整个字符串不能放入寄存器,对吧?寄存器可以存储字符串的地址,但不能存储字符串。另外,要学会调试——即逐行执行代码,同时检查寄存器和内存。

标签: assembly mips


【解决方案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

【讨论】:

    【解决方案2】:

    好吧,您似乎对syscall 8 有一些误解。您必须使用 输入缓冲区的地址加载 $a0,并使用 要读取的最大字符数加载 $a1 >.

    在您的代码中,您告诉系统调用输入缓冲区将覆盖first 的内容,这很好。但是,此时,$v08sw $v0, first 将在 first 中写入 0x8,因此在 $a0 中。所以你只是丢失了你的字符串。

    这应该可行:

    1) 开始为两个输入缓冲区保留空间。这可以通过firstread: .space 254 来完成。对lastread: .space 254 执行相同操作。

    2) 在$a0 中加载firstread 和在$a1 中加载253,应保留\n 的空间。使用syscall将字符串读取到firstread的地址。

    3) 在 $a0 中加载 lastread 并保留 $a1 的值。使用 syscall 读取字符串到 lastread 的地址。

    此时,您已读取两个字符串并将其存储在 内存 中。您不知道每个的大小,因此您必须遍历它们计算字节数,直到在每个中找到 null 字节 (0x0)。其余的很容易。您可以通过查看字节数轻松判断哪个更大或更小。尝试这样做,如果你不成功,请告诉我。

    【讨论】:

      猜你喜欢
      • 2020-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 2012-08-28
      相关资源
      最近更新 更多