【问题标题】:How to traverse an array in MIPS?如何在 MIPS 中遍历数组?
【发布时间】:2013-10-10 22:50:11
【问题描述】:

这只是我第二次处理 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

【问题讨论】:

  • “加载到数组中”是什么意思?值 5,2,3,10,7 已经在 X_INPUT 数组中,因为您在声明数组时将它们放在那里。您的意思是“从数组加载”吗?

标签: assembly mips


【解决方案1】:

当您看到的语法是 lw $t4, 0($t3) 时,听起来您正试图弄清楚如何访问数组的第 i 个元素。我想你已经知道你可以用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&lt;&lt;2。 (您避免了 MIPS Assembly language traversing an array 中的那个错误,但这些循环的底部有 j 而不是 bne,因此这些问答都没有很好地复制数组上的有效惯用循环。:/)
猜你喜欢
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 2011-10-30
  • 2022-01-21
  • 1970-01-01
  • 2014-01-13
  • 2021-01-10
相关资源
最近更新 更多