遍历 mips 程序集数组的最简单方法是什么? [英] What is the simplest way to iterate through a mips assembly array?

查看:68
本文介绍了遍历 mips 程序集数组的最简单方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以最干净的方式复制这个

I want to replicate this the most cleanest way possible

在蟒蛇中

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

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

That is, I want to iterate through an array and sets all its values to [10,10,10,10,10]

这就是我在 mips 程序集中所做的

This is what i've done in mips assembly

.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

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

I feel like I used so many registers and this isn't the most clean way to do this. Any help appreciated

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

(Also making sure to use a loop I could hard code this without a loop but im just trying to find out other ways to use loops)

推荐答案

.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

改动(在彼得的帮助下)

Alterations (w. help of Peter)

所以首先要做的是删除 i 变量.相反,我们可以将 $t2 的地址(指向数组的指针)与我们在循环外设置的端点($t1)进行比较,这将告诉我们我们完了.如果没有,则跳转到 start_loop.

So the first thing that was done is removing the i variable. Instead we can compare the address of $t2, the pointer into the array, with the end-pointer we set up outside the loop ($t1), that will tell us we are done. Branching to the start_loop if not.

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

Pointer-increments instead of redoing the indexing every time is especially good on machines like MIPS that don't have indexed addressing modes.

在循环底部使用条件分支进行循环意味着您不需要 j 指令,并且是所有 (?) ISA(例如 为什么循环总是编译成do...while"风格(尾跳)?).当您知道循环肯定会至少运行一次时,这尤其好,因此您不需要循环之前的分支来跳过它.

Looping with the conditional branch at the bottom of the loop means you don't need a j instruction, and is idiomatic for assembly language across all(?) ISAs (e.g. Why are loops always compiled into "do...while" style (tail jump)?). It's especially good when you know the loop will definitely run at least once, so you don't need a branch ahead of the loop to maybe skip it.

这篇关于遍历 mips 程序集数组的最简单方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆