在循环时理解MIPS

问题描述 投票:0回答:1

鉴于C中的传统while循环:

while(save[i] == k)
     i += 1;

MIPS的答案是这样的:

第一步是将save [i]加载到临时寄存器中。在我们将save [i]加载到临时寄存器之前,我们需要有它的地址。在我们将i添加到数组的基数以保存以形成地址之前,由于字节寻址问题,我们必须将索引i乘以4。幸运的是,我们可以使用左移逻辑,因为向左移位2位乘以22或4(参见前一节中的第88页)。我们需要为它添加标签Loop,以便我们可以在循环结束时分支回该指令:

Loop: sll $t1,$s3,2 # Temp reg $t1 = i * 4

要获取save [i]的地址,我们需要在$ s6中添加$ t1和save的基数:

add $t1,$t1,$s6 # $t1 = address of save[i]

现在我们可以使用该地址将save [i]加载到临时寄存器中:

lw $t0,0($t1) # Temp reg $t0 = save[i]

下一条指令执行循环测试,如果save [i]≠k则退出:

bne $t0,$s5, Exit # go to Exit if save[i] ≠ k

然后

addi $s3, $s3, 1 #i = i+1
j Loop # go to Loop
Exit: 

仍然有这个解释,我仍然无法得到它。

  1. 我不明白为什么我们要向左移2位。我不明白左/右逻辑的转换目的,我无法将在线解释与练习问题和例子联系起来。
  2. 因为我甚至没有得到第1步,所以我没有得到第2步,即在$ s6中添加转移结果($ t1)和保存基数。

基本上,我需要解释这个问题,因为即使有了答案,我也无法理解。我真的需要一个简单的(愚蠢的)解释,清楚地解释每一步以及为什么这样做。谢谢,麻烦您了!

mips
1个回答
0
投票

想象一下,您有从临时地址值开始的数据:

temp address V
             | ValueA | ValueB | ValuesC  |
Byte  offset  0  1 2 3  4 5 6 7  8 9 10 11
Array index   0         1        2

这假设每个'元素'是一个长度为4个字节的整数。

获取元素开头的地址时,可以看到它是4的倍数

MIPS并不关心地址(大小方面),因此您需要处理自己的问题。

所以第一个元素的地址是tempaddress + 0,第二个元素是tempaddress+(1*4)等。

或者当它更通用时,元素X在temp address + (X*4)

X * 4与向左移动X相同。

即:如果X是二进制中的值1,那就是0000 0001

左移2,即0000 0100或小数4。

如果X是二进制中的值3,那就是0000 0011

左移2,即0000 1100或小数6。

© www.soinside.com 2019 - 2024. All rights reserved.