迭代 mips 程序集数组的最简单方法是什么?

What is the simplest way to iterate through a mips assembly array?

我想以最干净的方式复制它

在python

A = [0,0,0,0,0]
i = 0
while(i != 5):
    A[i] = 10
    i++

也就是说,我想遍历一个数组并将其所有值设置为[10,10,10,10,10]

这是我在 mips 汇编中所做的

.data 
    array:  .word   0:5
    
.text
    
main:
    li $t1, 0       # i = 0
    la $t9, array       # $t9 = addr(array)
    li $t8, 10      # $t8 = 10
    

    
start_loop:
    beq $t1, 5, end_loop # if i == 5 jump to end loop
    
    sll $t2, $t1, 2     # $t2 = i x 4
    add $t2, $t9, $t2   # $t3 = addr(array[i])
    sw $t8, 0($t2)      # array[i] = $t8
    addi $t1, $t1, 1    # i = i + 1
    j start_loop

end_loop:

    li $v0, 10    # end program
    syscall

我觉得我用了很多寄存器,这不是最干净的方法。任何帮助表示赞赏

(还要确保使用循环,我可以在没有循环的情况下对其进行硬编码,但我只是想找出其他使用循环的方法)

.data 
    array:  .word   0:5
    array_end:
.text
    
main:
    la     $t2, array
    addiu  $t1, $t2, 20   # one-past-end address for loop condition
                 # or  la $t1, array_end  to avoid hard-coding length
    li     $v0, 10

start_loop:                  # do{
    sw     $v0, 0($t2)          # array[i] = $t8
    addiu  $t2,$t2,4            #increment pointer after
   beq $t1, $t2, start_loop  # }while(p != endp);

#end_loop:
    #li $v0, 10         # exit call number happens to be the same value we wanted to store
    syscall             # exit

改动(在 Peter 的帮助下)

所以要做的第一件事就是删除 i 变量。相反,我们可以将 $t2 的地址(指向数组的指针)与我们在循环外设置的结束指针 ($t1) 进行比较,这将告诉我们完成了。如果不是,则分支到 start_loop。

指针递增而不是每次都重做索引在像 MIPS 这样没有索引寻址模式的机器上特别好。

在循环底部使用条件分支循环意味着您不需要 j 指令,并且对于所有(?)ISA 的汇编语言来说都是惯用的(例如 ) .当你知道循环肯定会 运行 至少一次时,它特别好,所以你不需要在循环之前的分支来跳过它。

  .data
  array: .word 0:5

  .text
  main:
  li $t1, 0     #initialize i = 0
  la $t2, array #load address of array[0]
  li $t3, 10    #save 10 in a register 

  loop:
  beq $t1, 5, end       #if i == 5, end
  sw $t3, ($t2)     #array[i] = 10

  add $t2, $t2, 4   #increment array address pointer by 4
  add $t1, $t1, 1       #i = i + 1

  j loop


  end:
  li $v0, 10
  syscall