【发布时间】:2019-01-18 09:47:20
【问题描述】:
我对 MIPS 很陌生,如果这是一个愚蠢的问题,请原谅。 我有以下练习作为作业,如果有任何想法和起点,我将不胜感激。
我应该创建一个函数来接收参数 n(数字的数量),然后是 n 个数字,然后处理返回所述数字的总和并将其返回到堆栈中。 我该如何开始呢?我认为该函数可能有 4 个以上的数字,而实际数字的数量变化的事实让我感到困惑。 函数参数应如下所示:(int n, int number1, int number2....etc)。
我可以将数字存储在堆栈中,然后将堆栈用作函数中的参数吗?如果是这样,我该怎么做?
更新: 所以我现在的想法(在我收到的帮助下)看起来像这样:
sum:
addu $t3,$sp,16 #add to t3 address of sp+16
addu $a1,$a1,$a2 #adding sum to a1,a1 is first element a2 second and a3 third
addu $a1,$a1,$a3
li $t0,4 #start with i=4
bge $t0,$a0,end_for #while i<n
lw $v0,0($t3) #load v0 with value in stack
addu $a1,$v0,$a1 #add to sum
addi $t3,$t3,4 #increment stack and go up for next element
addi $t0,$t0,1
end_for:
li $v0,1
move $a0,$a0
syscall
jr $ra
我尝试按原样组装它,但我的 MARS 停止响应。有什么线索吗?
【问题讨论】:
-
你确定教授不是要你使用数组吗?您可以使用 varadic 函数来执行此操作,但如果调用约定传递寄存器中的第一个参数并且堆栈中没有归位,则实现需要一些预处理,否则会变得混乱。 MIPS 传递寄存器中的第一个参数,堆栈中的其余参数没有归位(我想),所以最好先澄清 n 个数字是如何传递的,然后再注册一个 varic 实现。
-
@MargaretBloom 是的,他说它应该相当于 C 中的 add(3,1,2,3), add (2,1,5) 之类的东西(第一个参数告诉我们接下来会有多少数字)
-
@MargaretBloom:MIPS 使用链接寄存器而不是推送返回地址,因此您可以将寄存器 args 与堆栈 args 连续存储以形成 args 数组。事实上,它也像 Windows x64 一样留下阴影空间。大概这么小的函数可以省去操作堆栈指针?例如所以他们可以在调用另一个函数之前将
$lr存储在那里?但是不,他们必须为被调用者保留影子空间,所以它只有助于需要溢出某些东西的叶子函数,我认为。似乎是一个糟糕的设计(尤其是与有一个红色区域相比)。也许是一些放松的约定? -
@PeterCordes 关于
$lr的好点子。我实际上没想到 MIPS 会有影子/归位空间。总而言之,这比预期的要容易。 -
@MargaretBloom:是的,我也很惊讶地发现它有影子/家庭空间,就像我在回答中所说的那样。没有它,它已经微不足道了,不像 x64,所以它的价值要低得多(我认为红色区域会是一个更好的选择)。但即使没有这些,剥离前 3 次迭代也很容易。可以是带有 2 个循环的单独数组,也可以是完全剥离/展开。
标签: assembly mips mars-simulator