如何在mips中将字符串保存到数组中

How to save string into an array in mips

我对这段代码有疑问。我尝试通过输入输入一个字符串并将其保存到一个数组中,这是我的代码:

    .data
    .align 2
array:  .space 80
size: .word 20
string: .space 20
op: .asciiz "Enter the array length"
prompt: .asciiz "Enter a string:"
text:   .asciiz "The array of string is:"
newline: .asciiz "\n"
    .text
    .globl main

main:
    add $t0, $zero, $zero # index of array
    addi $t1, $zero, 1 # counter=1

    li $v0, 4
    la $a0, op
    syscall
    jal new_line

    li $v0, 5
    syscall

    addi $s0, $v0, 0 # $v0 contains integer read
read_string: 
    bgt $t1, $s0, L1 # if ($t1 > length)then go to L1

    li $v0, 4
    la $a0, prompt
    syscall

    la $a0, string
    li $a1, 20
    li $v0, 8
    syscall

    sw $a0, array($t0)
    addi $t0, $t0, 4
    addi $t1, $t1, 1

    j read_string

L1: #### here i want to print the array ####
    add $t0, $zero, $zero # index of array
    addi $t1, $zero, 1 # counter=1

    la $a0, text
    li $v0, 4
    syscall
    jal new_line

    while: bgt $t1, $s0, done
    lw $t2, array($t0)

    li $v0, 4
    move $a0, $t2
    syscall
    jal new_line

    addi $t0, $t0, 4
    addi $t1, $t1, 1
    j while

    new_line: la $a0, newline
    li $v0, 4
    syscall
    jr $ra

done: li $v0, 10
    syscall

问题是这个程序显示了我输入的最后一个字符串,例如

Enter the array length:
2
Enter a string:asd
Enter a string:123
The array of string is:
123

123

我需要一些帮助,非常感谢,祝你有愉快的一天。

您的 array 索引逻辑似乎没问题,但问题是您总是存储 每个 条目 相同地址,string的地址。解决方案是在 存储 字符串时 增加 一个更大的 string 区域和一个指向它的指针。

我已经更正了您的代码 [未经测试]。请原谅不必要的样式清理,但在尝试修复它之前我需要了解您的逻辑。我添加了更多评论 [我是一个老 asm 人,我总是评论 每一 行] 并用 [OLD] 注释你的代码,用 [=16] 替换我的代码=].

    .data
    .align 2
array:      .space  80
size:       .word   20
###string:  .space  20          # [OLD]
string:     .space  20000       # [NEW]
op:         .asciiz "Enter the array length:"
prompt:     .asciiz "Enter a string:"
text:       .asciiz "The array of string is:"
newline:    .asciiz "\n"

    .text
    .globl main
main:
    # prompt user for array length
    li      $v0,4
    la      $a0,op
    syscall
    jal     new_line            # output newline

    # read in array count
    li      $v0,5
    syscall
    addi    $s0,$v0,0           # $v0 contains the integer we read

    add     $t0,$zero,$zero     # index of array
    addi    $t1,$zero,1         # counter=1
    la      $s2,string          # load address of string storage area [NEW]

read_string:
    bgt     $t1,$s0,L1          # if ($t1 > length) then array is done -- fly

    # prompt the user for next "string"
    li      $v0,4
    la      $a0,prompt
    syscall

    # get the string
### la      $a0,string          # place to store string [OLD]
    move    $a0,$s2             # place to store string [NEW]
    li      $a1,20
    li      $v0,8
    syscall

    # store pointer to string into array
    sw      $a0,array($t0)

    addi    $t0,$t0,4           # advance offset into pointer array
    addi    $t1,$t1,1           # advance iteration count
    addi    $s2,$s2,20          # advance to next string area [NEW]

    j       read_string

#### here i want to print the array ####
L1:
    add     $t0,$zero,$zero     # index of array
    addi    $t1,$zero,1         # counter = 1

    # output the title
    la      $a0,text
    li      $v0,4
    syscall
    jal     new_line

while:
    bgt     $t1,$s0,done        # more strings to output?  if no, fly
    lw      $t2,array($t0)      # get pointer to string

    # output the string
    li      $v0,4
    move    $a0,$t2
    syscall
    jal     new_line

    addi    $t0,$t0,4           # advance array index
    addi    $t1,$t1,1           # advance count
    j       while

# new_line -- output a newline char
new_line:
    la      $a0,newline
    li      $v0,4
    syscall
    jr      $ra

# program is done
done:
    li      $v0,10
    syscall

UPDATE 为了获得额外的奖励,当您使用原始版本时,您可以尝试将 addi $s2,$s2,20 替换为 jal stradv,其中 stradv是:

# stradv -- advance past end of string
stradv:
    ldb     $t2,0($s2)          # get char
    addi    $s2,$s2,1           # we pre-increment because we want EOS + 1
    bne     $t2,$zero,stradv    # is it EOS?  if no, loop some more
    jr      $ra

这将允许较大的可变长度字符串[如果您还增加了字符串读取系统调用的长度]。

这就是我通常编写类似代码的方式,但在基本代码完全可用之前我不想添加它。