MIPS Assembly 为什么这些寄存器加载相同的数组值?

发布于 2025-01-14 02:28:51 字数 485 浏览 1 评论 0原文

我正在尝试加载第一个和第二个位置的数组值,但由于某种原因它只加载第一个位置的值?花了一个小时试图弄清楚,但没有成功。这是我的代码。我将 $t1 设置为 0,将 $t3 设置为 4,所以我应该加载第一个和第二个值,但它只加载 $t1 和 $t3 的第一个值?

 addi $t1, $zero, 0 
 addi $t3, $zero, 4
 
 
 
 FindLessThenLoop:
 la $t1, myArray # Load first number
 addu $t1, $zero, $t1 # add offset and base together
 lw $t1, ($t1)      # fetch the data 
 
 la $t3, myArray # Load second number
 addu $t3, $zero, $t3 # add offset and base together
 lw $t3, ($t3)      # fetch the data 

I'm trying to load in array values in the first and second position but for some reason it's loading in only the value in the first position? Been trying to figure it out for an hour but no luck. This is the code I have. I set $t1 to 0 and $t3 to 4 so I should be loading in the first and second value, yet it only loads in the first value for both $t1 and $t3?

 addi $t1, $zero, 0 
 addi $t3, $zero, 4
 
 
 
 FindLessThenLoop:
 la $t1, myArray # Load first number
 addu $t1, $zero, $t1 # add offset and base together
 lw $t1, ($t1)      # fetch the data 
 
 la $t3, myArray # Load second number
 addu $t3, $zero, $t3 # add offset and base together
 lw $t3, ($t3)      # fetch the data 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月寒剑心 2025-01-21 02:28:51

除了使用不同的寄存器之外,第一个和第二个的代码本质上是相同的,因此,我们期望相同的结果:数组位置/索引 0 中的值。

要获取第二个元素,您可以执行以下任一操作:

la $t3, myArray     # Load second number
addiu $t3, $t3, 4   # add offset and base together
lw $t3, ($t3)       # fetch the data 

- 或 -

la $t3, myArray     # Load second number
lw $t3, 4($t3)      # fetch the data with offset 4

如果您要在循环中进行变量索引(例如 a[i]),您会更喜欢第一种形式的变体,而第二种形式用于常量索引(例如 a[1])。

如果您有整数索引,则以下内容很有用:

# usually done outside of and before a loop:
la $t3, myArray     # Load second number

# this part done inside a loop:
sll $t4, $t2, 2     # scale the integer index by 4
addu $t4, $t3, $t4  # add base and offset
lw $t1, ($t4)       # fetch the data 

请注意以下事项:

  1. $t3 的预循环设置,
  2. 在循环内 我们保留 $t3,以便它可以每次迭代时,
  3. 我们都会根据元素的大小(4x)缩放简单整数索引。

另一种选择是指针,它在汇编中相当容易,但建议首先将算法转换为 C 中的指针,然后再进行汇编。

指针将基址 + 缩放偏移量的概念组合到一个变量中。指针可以递增以引用下一个元素。


这是一个简单的说明性循环,假设元素为正,则计算数组的最大值:

    li $t0, array # t0 is the base array address: &array[0]
    li $t1, 0     # t1 is min value variable, initially zero
    li $t2, 0     # t2 is the index, aka loop control variable call it "i"
    li $t3, 10    # where to stop with "i"

loop1:
    beq $t2, $t3, loop1End   # if "i" == 10 we're done

    sll $t4, $t2, 2          # scale index by 4 due to word-sized elements
    add $t4, $t0, $t4        # add base and scaled offset
    lw $t4, 0($t4)           # fetch element from a[i]

    ble $t4, $t1, if1End
    move $t1, $t4            # capture the new max, if larger
if1End:

    addi $t2, $t2, 1         # next index position
    j loop1

loop1End:
    ...                      # t1 holds max value from the array

The code for the first and the second are essentially the same except using a different register, so, we would expect the same results: the value from array position/index 0.

To get the second element, you can do either:

la $t3, myArray     # Load second number
addiu $t3, $t3, 4   # add offset and base together
lw $t3, ($t3)       # fetch the data 

-or-

la $t3, myArray     # Load second number
lw $t3, 4($t3)      # fetch the data with offset 4

You'll prefer a variation of the first form if you're going to do variable indexing (e.g. a[i]), say in a loop, whereas the second form is for constant indexing (e.g. a[1]).

If you have an integer index, then the following is useful:

# usually done outside of and before a loop:
la $t3, myArray     # Load second number

# this part done inside a loop:
sll $t4, $t2, 2     # scale the integer index by 4
addu $t4, $t3, $t4  # add base and offset
lw $t1, ($t4)       # fetch the data 

Note the following:

  1. there is pre-loop setup of $t3
  2. inside the loop we preserve $t3 so it can be used each iteration
  3. we scale the simple integer index by size of the elements (4x)

An alternative is pointers, which are fairly easy in assembly, but suggest to convert your algorithm to pointers in C first, then take to assembly.

A pointer combines into one variable the notion of base + scaled offset.  A pointer can be incremented to refer to the next element.


Here's a simple illustrative loop that does max value of array, assuming elements are positive:

    li $t0, array # t0 is the base array address: &array[0]
    li $t1, 0     # t1 is min value variable, initially zero
    li $t2, 0     # t2 is the index, aka loop control variable call it "i"
    li $t3, 10    # where to stop with "i"

loop1:
    beq $t2, $t3, loop1End   # if "i" == 10 we're done

    sll $t4, $t2, 2          # scale index by 4 due to word-sized elements
    add $t4, $t0, $t4        # add base and scaled offset
    lw $t4, 0($t4)           # fetch element from a[i]

    ble $t4, $t1, if1End
    move $t1, $t4            # capture the new max, if larger
if1End:

    addi $t2, $t2, 1         # next index position
    j loop1

loop1End:
    ...                      # t1 holds max value from the array
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文