-1

我的教科书中给出了以下汇编代码。

Loop:
sll $t1, $t0, 2 
add $t2, $a0, $t1
sw $zero, 0($t2)

addi $t0, $t0, 1
slt $t3, $t0, $a1
bne $t3, $zero, Loop

# return where we were
jr $ra

从这段代码中,我有两个问题要问。

第一个问题是关于从顶部开始的第二行。我知道该指令sll向左移位的逻辑左移。由于移位量为 2,因此十进制0000 -> 0100 = 4。但是在第一个循环之后我没有得到它。如果我们把它向左移动 2,它乘以 4 不就多了吗?

第二个问题是是否可以优化这段代码?在我看来,我可以sll在代码中修改和添加部分,但我不确定。任何意见??

4

3 回答 3

1

左移将插入 0,而不是 1。所以 0000 仍然是 0000,移位后 0001 会变成 0100

于 2013-10-04T02:51:57.787 回答
0

[是否]可以优化此代码?

做同样事情的更紧凑的方法是:

sll $a1, $a1, 2
addu $a1, $a1, $a0   # $a1 = $a1 * 4 + $a0
Loop:
sw $zero, ($a0)
addiu $a0, $a0, 4
bne $a0, $a1, Loop

我正在做这些假设:

  • 循环结束后不再需要$a0和的原始值。$a1如果需要它们请在进入循环之前将原始值保存在某处(在其他寄存器或堆栈中),然后再恢复它们。
  • $t0从零开始。如果没有,您必须$t0 * 4$a0循环之前添加。我还假设$t0退出循环后的值无关紧要。
于 2013-10-04T09:21:45.363 回答
0

考虑以下二进制文件:

0000 0001

如果将位左移 1 位,您将得到:

0000 0010

如果再次左移 1 位:

0000 0100

然后再次:

0000 1000

上面的二进制值等价于1;1x2=2;2x2=4;4x2=8。如果 N 是您要移位的位数,则左移位是将值乘以 2^N。

转移的另一个例子:

Assume $t1 contains 0000 1111

sll $t0, $t1, 3    # $t0 = $t1 * 2^3

Now $t0 contains 0111 1000

您可以通过执行十进制乘法来验证这一点。15 * 8 = 120。

于 2013-10-04T23:46:17.893 回答