So I've been bouncing around from site to site (Sites like this really helped me out: http://www.cs.uiuc.edu/class/fa05/cs232/html/L4.pdf ) but I can't seem to find my answer in the most simplistic terms. (Oddly enough, I'm not TOO shabby at coding with MIPS in MARS and such, I'm just not getting this concept that much. I'm actually quite knowledgeable about the language itself, or so I'd like to think. After realizing I'm getting stuck on something like this, I'd like to say that I'm not that confident. Lol.)

I want to understand returning in MIPS. I understand that there are two return registers ($v0, $v1) yet most of the time they end up getting "clobbered"/overwritten when you end up doing a syscall or something. Why is this helpful at all?

Another question, arguments are stored in the $a0-$a3 registers. Yet they are also often overwritten in the print and such system calls. Why is this so? How do I keep an original argument stored in one register (such as $a0) yet when I want to print it out, I have to overwrite it?

So, my difficulty here: I'm working on some HOMEWORK for my CptS 260 class, and I'm doing a pretty simplistic project. I'm creating a function that counts the length of a string. Here it is:

.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

I've already seen this one: (string length for mips assembly) and gotten some ideas from it. Yet, mine decides to infinitely loop on the segment I've labeled as infinitely looping. Why is this so? Do I need to use a stack for this?

Additionally, My teacher grades these projects by bypassing my main block, and creating his own. Which is roughly him doing a bunch of different test cases by inserting different arguments. He also wants us to return $v0 as the answer of the length. Would I just do a simple: move $v0, $t0 (Where I'm moving the length of the string to the return register) at the end of one of my blocks? It would have to be in the code besides "main:" since he bypasses mine.

EDIT: This is only one task of multiple throughout my project. Later, I'll have to include this project and incorporate it in another project I'm writing. (Specifically, a palindrome-checker.) So would it just be better now to start using the $sp and stack?

Any help would be appreciated! Even just a knowledge briefing. If I wasn't specific enough, please feel free to ask questions!

Thank you very much for your time!

-CozmoNaught

有帮助吗?

解决方案

First remember that with function calls you are dealing with a stack (like in Java or C++ or most HLL), so like in any recursive call the values of a and v registers depend on stack level, you must save them if you do not want to lose them from level to another.

In your first (and second) code you are over complicating things, you don't need that many 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

you had added 2 lines you don't need and they create an infinite loop (you call and return at same address infinitely).

其他提示

Actually, I may have just solved it using stacks.

Now it doesn't infinitely loop, and it prints the correct answer!

.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

I think this is valid now!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top