MIPS问题:返回($ v0),参数,jal和jr $ ra(包含代码)

时间:2014-03-10 21:28:20

标签: string assembly mips infinite-loop mars-simulator

所以我一直在各个站点之间蹦蹦跳跳(像这样的网站真的帮助了我:http://www.cs.uiuc.edu/class/fa05/cs232/html/L4.pdf)但我似乎无法用最简单的术语找到答案。 (奇怪的是,我在MARS中使用MIPS进行编码并不是太糟糕了,我只是没有得到这么多的概念。我实际上对语言本身非常了解,或者我想这么想。在意识到我被困在这样的事情之后,我想说我不那么自信。大声笑。)

我想了解返回MIPS。我知道有两个返回寄存器($ v0,$ v1)但是大多数时候他们最终会在你结束时被“摧毁”/覆盖做一个系统调用或其他什么。为什么这有用呢?

另一个问题,参数存储在$ a0- $ a3寄存器中。然而,它们也经常被印刷和系统调用覆盖。为什么会这样? 如何将原始参数保存在一个寄存器中(例如$ a0)但是当我要将其打印出来时,我必须覆盖它?

所以,我的困难在于:我正在为我的CptS 260课程开发一些 HOMEWORK ,而我正在做一个非常简单的项目。 我正在创建一个计算字符串长度的函数。 这是:

.data
string: .asciiz "hello"
message: .asciiz "The string length is: "

.text

main: #  ** The test case! **
la $a0, string
jal strlen

li $v0, 4       # Prints the message for the string length
la $a0, message
syscall

li $v0, 1       # Moves the length of the string to $a0, to print.
move $a0, $t0
syscall

li $v0, 10 #Exit
syscall

strlen:
li $t0, 0       #Initializes counter for len
jal loop
jr $ra      #Infinitely Loops here when compiled.

loop:
lbu $t1, 0($a0)
beqz $t1, done # Branches to "done" at the null character.
addi $a0, $a0, 1 #increment character
addi $t0, $t0, 1 #increment counter
j loop

done:
jr $ra

我已经看过这一个:(string length for mips assembly)并从中得到了一些想法。 然而,我决定在我标记为无限循环的片段上无限循环。为什么会这样?我需要使用堆栈吗?

此外,我的老师绕过我的主要部分并创建自己的项目来评分这些项目。这大致是他通过插入不同的参数来做一堆不同的测试用例。他还希望我们返回$ v0作为长度的答案。我会做一个简单的事情:在我的一个块的末尾移动$ v0,$ t0(我将字符串的长度移动到返回寄存器)?除了“main:”之外,它必须在代码中,因为他绕过了我的。

编辑:这只是我整个项目中的一项多项任务。之后,我将不得不包含这个项目并将其合并到我正在编写的另一个项目中。 (具体来说,是回文检查器。)那么现在开始使用$ sp和堆栈会更好吗?

任何帮助将不胜感激!即使只是一个知识简报。如果我不够具体,请随时提问!

非常感谢你的时间!

-CozmoNaught

2 个答案:

答案 0 :(得分:3)

首先请记住,对于函数调用,您正在处理堆栈(如Java或C ++或大多数HLL),因此在任何递归调用中,a和v寄存器的值都取决于堆栈级别,如果您需要保存它们不想让他们从一个级别丢失到另一个级别。

在你的第一个(和第二个)代码中,你过度复杂化了,你不需要那么多jr

.data
string: .asciiz "hello"

message: .asciiz "The string length is: "

.text

main: #  ** The test case! **
la $a0, string
jal strlen

li $v0, 4       # Prints the message for the string length
la $a0, message
syscall

li $v0, 1       # Moves the length of the string to $a0, to print.
move $a0, $t0
syscall

li $v0, 10 #Exit
syscall

strlen:
li $t0, 0       #Initializes counter for len

loop:
lbu $t1, 0($a0)
beqz $t1, done # Branches to "done" at the null character.
addi $a0, $a0, 1 #increment character
addi $t0, $t0, 1 #increment counter
j loop

done:
jr $ra

你添加了2条你不需要的行,它们创建了一个无限循环(你无限地调用并返回相同的地址)。

答案 1 :(得分:0)

实际上,我可能刚刚使用堆栈来解决它。

现在它没有无限循环,它打印出正确的答案!

.data
string: .asciiz "hello"
message: .asciiz "The string length is: "

.text

main: #  ** The test case! **
la $a0, string
jal strlen

li $v0, 4       # Prints the message for the string length
la $a0, message
syscall

li $v0, 1       # Moves the length of the string to $a0, to print.
move $a0, $t0
syscall

li $v0, 10 #Exit
syscall

strlen:
addi $sp, $sp, -8 #Storing two values ($v0, and $ra)
sw $ra, 0($sp)
sw $v0, -4($sp)
li $t0, 0       #Initializes counter for len
jal loop

loop:
lbu $t1, 0($a0)
beqz $t1, done # Branches to "done" at the null character.
addi $a0, $a0, 1 #increment character
addi $t0, $t0, 1 #increment counter
j loop

done:
move $v0, $t0
sw $v0, -4($sp) #Replaces the original $v0
lw $ra, 0($sp)
addi $sp, $sp, 8
jr $ra

我认为现在这是有效的!