我试图在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:
答案 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指令,或承诺使用某些寄存器,只需纯注释。然后决定寄存器使用情况(主要值)。然后用实现它的特定指令填写每个评论。在尝试同时执行所有算法,语法和寄存器分配时,通常有助于避免被太多细节淹没。