如何在MIPS中遍历数组?

3

这是我第二次处理MIPS汇编(即任何类型的汇编),请温柔一点。所以我从头开始制作了一个用于MIPS的乘法函数。那比我想象中容易——我测试了它,对于一个值它完美地工作。 不幸的是,当数组出现时,我完全迷失了方向。

我甚至不知道如何入手。我感到很愚蠢,因为我不能问一个具体的问题,因为我不理解这个大的思路。我为数组分配了空间,有常量值,但不知道如何:

A.)将常量值(例如5、2、3、10、7)加载到数组中。

B.)启动我的外部循环。

我的代码如下,我只需要一种方法来启动我的外层循环。 有什么建议吗?

/*
Name: MrPickl3
Date: October 10, 2013
Purpose:  Program creates a multiply function from scratch.  Uses two arrays to
      test the program.
*/

#include <xc.h>

. data

X: .space 80
Y: .space 80
N: .space 4
MAC_ACC .word 0x00000000

    .text
    .globl main

main:
    li t0, 0x00000000 //i = 0
    li t1, 0x00000005 //Offset of array
    li t2, MAC_ACC //Mac_acc (i.e. product register)
    lw t9, 0(t2) //Refers to MAC_ACC's data
    la t3, X //Address of X[0]
    lw t4, 0(t3) //Data of X
    la t5, Y //Address of Y[0]
    lw t6, 0(t5) //Data of Y

loop:
    addiu t0, t0, 4 //i++

//t4 = x[i]
//t6 = y[i]
//t7 = counter

mult:
    beq  t6, 0, loop  //Check if y = 0.  Go to loop, if so.
    andi t7, t6, 1    /*We want to know the nearest power of two.
                      We can mask the last bit to
                      test whether or not there is a power of two
                      left in the multiplier.*/
    beq  t7, 0, shift //If last bit is zero, shift
    addu t9, t9, t4   //Add multiplicand to product

shift:
    sll t3, t3, 1 //Multiply x[i] by 2
    srl t4, t4, 1 //Multiply y[i] by 2

lab2_done:
    j lab2_done
    nop

.end main

X_INPUT: .word 5,2,3,10,7
Y_INPUT: .word 6,0,8,1,2
N_INPUT: .word 5

“load into the arrays” 是什么意思?因为在声明数组时,值 5、2、3、10、7 已经在 X_INPUT 数组中了,所以你把它们放在那里。你是不是指“从数组中加载”? - Michael
1个回答

1
看起来你正在尝试找出如何访问数组的第i个元素,当你看到的语法是lw $t4, 0($t3)。我认为你已经知道可以使用lw $t4, 4($t3)获取下一个单词,但你卡在了如何使索引动态上。
关键是你不改变立即值(0、4、8等)。相反,你改变在上述示例中指向数组第一个单词的寄存器的内容。
这是我在我的CompArch课程作业中编写的代码,用于实现一个简单的do-while循环,将数组成员初始化为零。我们被告知$s0已经加载了数组中第一个单词的地址。
我得到了我想要的元素的偏移量,乘以4(左移两位),然后将该偏移量添加到$s0(第一个单词)中。现在,$t1指向我想要设置的int。我所要做的就是将值($zero)存储在$t1指向的地址中。
        .text 
partC:  # Implement a do-while loop (0-100)
        add $t0, $zero, $zero # i=0
Cstart: # Get offset to current int
        sll $t1, $t0, 2  # *4
        add $t1, $s0, $zero
        sw $zero, ($t1)
        add $t0, $t0, 1  # i++
        blt $t0, 100, Cstart # i < 100
Cdone:  add $v0, $zero, 10 # terminate program
        syscall 

请注意,语法sw $zero, ($t1)只是sw $zero, 0($t1)的伪操作符。
希望这有助于理解基本概念!

在循环内部重新索引时,您不需要进行移位和加法操作,只需增加指针(并针对您在循环外部计算的结束指针执行bne)。此外,您每次都会执行t1 = s0 + 0,覆盖了t1中的i<<2。(您在MIPS汇编语言遍历数组中避免了该错误,但这些循环在底部具有j而不是bne,因此这两个问题都不适合用作数组高效惯用循环的重复。 :/) - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接