【问题标题】:Loading array value into another array value将数组值加载到另一个数组值中
【发布时间】:2016-08-15 11:53:14
【问题描述】:

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

我遇到了一些麻烦:

答:

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

乙:

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:

【问题讨论】:

    标签: assembly mips mips32


    【解决方案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 - 这写为“将值 v 加载到内存中”,在人类逻辑中与“将值 v 存储到内存中”相同,但 MIPS 只有第二种方式:sw $s5,myArray($s4)


    补充说明: 为什么你把所有的$s# 寄存器都弄得乱七八糟,而不是使用临时的$t#?您不必存储/恢复 $t# regs 的值,因此它可能会使您免于漫长的初始化(以及长时间的退出,如果您将其包括在内)。

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

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

    slt $t5, $s2, $s1 # check if a1 &gt; s2 - 请不要这样做。我的意思是评论。如果您在一年后阅读这篇文章,您会发现该评论很荒谬(= 正确、明显且无用)。

    试试# check if size (a1) &gt; i (s2),会好一点,但它颠覆了slt 的逻辑。所以# set t5 if i (s2) &lt; array size (s1) 是我的最终建议(注意我是如何摆脱a1 的,因为你不再使用它了)。

    编辑: 在有问题的行lw myArray($s4), myArray($s6)# alist[position] = alist[position-1] 上,您做得对,您没有评论指令的作用(这对于任何了解 MIPS ASM 的人来说都很明显),但您评论了您通过该指令实现的人类意图。保持这种状态。但是您可能会发现很难以这种方式注释每一行,因为某些行自然分组(例如slt + beq),然后在指令组之前用单行注释您的意图。

    您实际上可以使用它通过几个简单的步骤首先编写您的算法,而无需任何 ASM 指令,或承诺使用某些寄存器,只是纯 cmets。然后决定寄存器的使用(主要值)。然后用实现它的特定说明填写每个评论。在尝试同时进行所有算法、语法和寄存器分配时,通常有助于避免过多的细节使您不知所措。

    【讨论】:

      猜你喜欢
      • 2020-10-06
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      相关资源
      最近更新 更多