将数组值加载到另一个数组值中

时间:2016-08-15 11:53:14

标签: assembly mips mips32

我试图在MIPS MARS 4.5中进行插入排序。

我特别遇到了一些麻烦:

A:

lw  myArray($s4), myArray($s6)# alist[position] = alist[position-1]

B:

lw  myArray($s4), $s5   # alist[position] = current value

我遇到的问题是"太多或不正确地形成操作数"和" myArray操作数分别是不正确的类型"。

基本上,我在评论中提到了我试图用A来做的事情,我试图制作myArray($ s4)= myArray($ s6),但它不会让我lw / la,我也尝试过添加移动它。

对于附件B我想将myArray($ s4)中的值更改为$ s5中的值

任何人都能帮我解决我应该在这里使用的运营商吗? 感谢

如果需要,我已将以下功能的其他部分联系起来。

再次感谢。

sort:
    addi    $sp, $sp, -32       # save values on stack
    sw  $ra, 0($sp)     # Store the saved values on the stack to restore when done
    sw  $s0, 4($sp)     # s0 = base address of array
    sw  $s1, 8($sp)     # s1 = size of array
    sw  $s2, 12($sp)        # s2 = i
    sw  $s3, 16($sp)        # s3 = j
    sw  $s4, 20($sp)        # s4 = position
    sw  $s5, 24($sp)        # s5 = currentvalue
    sw  $s6, 28($sp)        # s6 = position - 1

    la  $a0, myArray        # load array address into a0
    la  $a1, myArray($s2)   # load size of array into a1
    move    $s0, $a0        # move array address into s0
    move    $s1, $a1        # move size of array into s1
    li  $s2, 0          # set i to 0
    li  $s3, 0          # set j to 0
    li  $t0, 0          # set t0 to 0
 iloop:
 # if s1 >= size of array go to end
    slt $t5, $s2, $s1       # check if a1 > s2
    beq $t5, 0, endWhile    # if it is, jump to the end

    lw  $s5, myArray($s2)   # currentvalue = alist[i]
    add $s4, $zero, $s2     # position = i
    sub $s6, $s4, 4     # position - 1
    j   jloop           # else go to jloop
 jloop:
 # if position is <= 0
    slt $t5, $s4, $t0       # check if s4 is greater than 0
    beq $t5, 0, iloop       # if its less, jump to the end                
 # and alist[position-1] < currentvalue
    slt $t5, $s6, $s5       # check if alist[position-1] > current value
    beq $t5, 0, iloop       # if less than jump back to iloop
    lw  myArray($s4), myArray($s6)# alist[position] = alist[position-1]
    sub $s4, $s4, 1     # position = position - 1
    j   setArray
 setArray:
    lw  myArray($s4), $s5   # alist[position] = current value
    j   iloop
 endWhile:

1 个答案:

答案 0 :(得分:1)

(免责声明:我从未做过MIPS汇编程序,所以我只是跟随wiki跟我的其他汇编知识,因此我极易受到一些愚蠢的错误或语法错误的影响,如果有的话请告诉我不起作用)

lw myArray($s4), myArray($s6) - 您无法访问“加载/存储”(移动)两侧的内存。这在CPU上太多了,只有一方可以进行内存访问,另一方面必须是寄存器

lw $t5,myArray($s6) # $t5 set to alist[position-1]
sw $t5,myArray($s4) # alist[position] set to $t5

lw myArray($s4), $s5 - 这被写为“将值加载到内存中”,这在人类逻辑中与“将值存储到内存中”相同,但MIPS只有第二种方式:sw $s5,myArray($s4)

附加说明: 为什么混乱所有$s#寄存器而不是使用临时$t#?您不必存储/恢复$t# regs的值,因此它可能会使您从那个长init(以及长退出,如果您将其包含在其中)中保存起来。

可能使用$zero代替0。 (除非汇编程序足够聪明,可以将li $s2,0更改为add $s2,$zero,$zero。如果MIPS与其他旧CPU设计接近,那么这应该是“更好的方式”,而不是立即为零(尽管任何现代内置的MIPS CPU可能不会在两者之间产生任何差异。)

为什么myArray硬编码?你不能把它作为一个程序,把数组指针和它的大小作为$a0, $a1的参数吗?

slt $t5, $s2, $s1 # check if a1 > s2 - 请不要这样做。我的意思是评论。如果你在一年之后读到这篇文章,你会发现这个评论很荒谬(=正确,明显和无用)。

尝试# check if size (a1) > i (s2),这会更好,但它会翻转slt的逻辑。所以# set t5 if i (s2) < array size (s1)是我的最终建议(注意我如何摆脱a1,因为你不再使用它。)

编辑: 在有问题的行lw myArray($s4), myArray($s6)# alist[position] = alist[position-1]你做得对,你不评论指令的作用(对于任何知道MIPS ASM的人来说这是显而易见的),但你评论你的人类通过该指令实现的意图是什么。保持这样一个。但是你可能会发现以这种方式评论每一行变得很困难,因为一些行自然地组(如slt + beq),然后在指令组之前用单行评论你的意图

您可以实际使用它来编写您的算法,只需几个简单的步骤,无需任何ASM指令,或承诺使用某些寄存器,只需纯注释。然后决定寄存器使用情况(主要值)。然后用实现它的特定指令填写每个评论。在尝试同时执行所有算法,语法和寄存器分配时,通常有助于避免被太多细节淹没。