我刚刚写了这个程序:
countzeroes:
li $v0, 0 # count = 0
li $t0, 0 # int i = 0
li $v1, 1 # compare bit = 1
cz_loop:
bge $t0, 32, cz_exit # exit loop if i >= 32
andi $t1, $a0, 1 # bit = arg0 & 1
beq $t1, $v1, cz_skip # skip if bit = 1
addi $v0, $v0, 1 # adds 1 to count
cz_skip:
srl $a0, $a0, 1 # shifts input right by 1
add $t0, $t0, 1 # i++
j cz_loop
cz_exit:
jr $ra
非常简单,只需计算32位字中的零个数。我想知道该程序如何知道如何在最后返回$ v0?我知道v0和v1是返回寄存器,但我想知道这两个是否总是返回。如果没有,程序如何知道返回v0?
另外,我知道jr $ ra会跳转到返回地址 - 但这意味着什么?
感谢您的帮助。
答案 0 :(得分:2)
“程序如何知道如何在结尾处返回$ v0?”
它不知道,你在$ v0中写了“return”值,实际上你可以在任何可用的寄存器中返回“结果或返回值”,例如时间,这只是一个约定使用$ v0注册以返回值(以MIPS表示)。
“我想知道这两个人是否总是被退回”
请记住,在程序的任何子程序中,您始终可以访问所有寄存器,因此对于可以在语义上称为“返回值”的寄存器存储值没有“限制”,因此我可以轻松创建一个返回3的方法$ t0,$ t1,$ t2中的数字,但这是我的选择,你也可以返回堆栈中的值,有很多可能性,这取决于并优先考虑良好的编程实践以及 调用约定 ,在这里您可以找到MIPS调用约定:https://courses.cs.washington.edu/courses/cse410/09sp/examples/MIPSCallingConventionsSummary.pdf
“jr $ ra跳转到返回地址 - 但这意味着什么?”
程序按指令执行(程序有一个指令指针,也就是程序计数器),当你调用子程序时,下一条指令的地址存储在$ ra寄存器中,然后当你进行jr $ ra时,程序执行返回到该地址(指令指针获取$ ra的值)。
答案 1 :(得分:2)
在MIPS中,您会看到三种不同的跳跃。 j,jr& JAL。
j:它被视为无条件跳跃。只需这样做:
j function
jr:aka跳转到注册。正如名字听起来你跳到注册。这是当你有一个寄存器已经保存在你希望跳回的程序的某个地方。它通常看起来像这样:
jr $ra
$ ra是之前在你的jal(见下文)之前预留的寄存器,它会将程序跳回到该地址。
jal:aka跳转和链接将下一条指令的地址复制到寄存器中,然后跳转到地址标签。换句话说,jal和jr都是相互结合使用的,主要是为了进入通常在退出调用之后放置的函数。
例如:
main:
#program
jal function
#continue with program
function:
#
#do something
#
jr $ra
此外,我开始学习时最有用的网站:http://logos.cs.uic.edu/366/notes/mips%20quick%20tutorial.htm
我希望有人在我开始时告诉我一些其他快速提示: