将C数组操作转换为Assembly

时间:2016-09-01 00:38:27

标签: assembly mips

我正在努力将a[i+1] = a[i-1] + b[4]转换为汇编。如果$s0a的地址,则$s1b的地址,$s2是变量i。教授提到它可以分6步完成。

我有:

addi $t0, $s2, 4 #i + 1

addi $t1, $s2, -4 #i - 1

lw $t2, $t1($s0) #load a[i-1] - I know this is wrong

lw $t3, 16($s1) #load b[4]

add $t4, $t2, $t3 #add a[i-1] + b[4]

sw $t4, $t0($s0) #save to a[i+1] - I know this is wrong

我所知道的地方哪里出错了,我知道我不能立即使用寄存器,但我不确定如何解决这个问题。我可能也会这样做完全错了,感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

以下是一些我认为可行的带注释的代码:

    .text

    .globl  main
# main -- main program
#
# a[i + 1] = a[i - 1] + b[4]
#
# arguments:
#   s0 -- address of a
#   s1 -- address of b
#   s2 -- i
#
# registers:
#   t0 -- address of a[i]
#   t1 -- value of b[4]
#   t2 -- i << 2 (i.e. a byte offset)
#   t3 -- value of a[i - 1]
#   t4 -- a[i - 1] + b[4]
main:
    sll     $t2,$s2,2               # get i << 2
    add     $t0,$s0,$t2             # get &a[i]

    lw      $t3,-4($t0)             # get a[i - 1]
    lw      $t1,16($s1)             # get b[4]

    add     $t4,$t3,$t1             # sum them
    sw      $t4,4($t0)              # a[i + 1] = sum

这非常接近可以使用的 only 序列。可以翻转lw指令的顺序,但是除非使用不同的寄存器来保存不同的值,否则指令必须必须

对于清晰度,每个中间术语/步骤都有自己的t寄存器。但是,如果重新分配/重用寄存器,我们可以减少使用的寄存器数量。例如,在前两条说明中,我们可以将$t2替换为$t0,因为我们之后从不使用$t2

优化编译器可以/将会这样做。我们最终只需要$t0-$t2而不是$t0-$t4

    .text

    .globl  main
# main -- main program
#
# a[i + 1] = a[i - 1] + b[4]
#
# arguments:
#   s0 -- address of a
#   s1 -- address of b
#   s2 -- i
#
# registers:
#   t0 -- i << 2
#         address of a[i]
#   t1 -- value of b[4]
#   t2 -- value of a[i - 1]
#         sum of a[i - 1] + b[4]
main:
    sll     $t0,$s2,2               # get i << 2
    add     $t0,$s0,$t0             # get &a[i]

    lw      $t2,-4($t0)             # get a[i - 1]
    lw      $t1,16($s1)             # get b[4]

    add     $t2,$t2,$t1             # sum them
    sw      $t2,4($t0)              # a[i + 1] = sum

如果代码是函数的一部分,我们可以使用$v0, $v1, $a0作为临时寄存器,因为允许函数使用$v0-$v1$a0-$a3作为内部临时函数。< / p>

<强>更新

  

这些评论肯定有助于我理解每条指令中发生的事情

良好的编程风格[因此理解]有很多评论。正确的类型。对于asm来说,这尤其非常重要,因为在C中,像number_of_users这样的变量有点描述性。但是,$t0不是。

我添加的评论是我为自己编写的任何asm代码所做的。而且,我已经写了几十年了。

此外,&#34;优化&#34;版本有一个目的:简化。通过释放$t3-$t4,它们可用于保存其他内容。在一个更复杂的功能中,这可以区分简单易懂的功能,以及难以理解和维护的不必要的复杂功能。

有关此问题的更多信息以及如何根据自己的经验编写asm的提示,请参阅我的回答:MIPS linked list

  

教授并不是传递信息的最佳人选

在教室环境中只能传达这么多东西。它可以涵盖基础知识。而且,课程可以帮助您学习给定语言的基础知识。而且,IMO,教授从未特别擅长评论代码[足够; - )]。

当我学习asm [在不同的架构上]时,除了课程作业外,我还能够在多用户分时操作系统上作为付费程序员工作,该操作系统是100%用asm编写的。它具有与上述相同的评论风格。

IMO,最好的学习方法之一是分析&#34;专家&#34;码。提出问题:&#34;为什么他们以 的方式做到了?&#34;。这就是我所做的,我学到了很多东西。到目前为止,我仍然赞赏这种经历。

答案 1 :(得分:1)

temp0 = $s0 + $s2
temp2 = load -4(temp0)
temp3 = load 16($s1)
temp1 = temp2 + temp3
store +4(temp0) = temp1