I\'m working on a mips program that will run on pcspim and i need a little help. The description of the program is: Write a program that reads a string (from a keyboard), stores
@mjshultz
i've changed it up a little. Didnt think i needed 2 loops. Also i've increment it by four because i thought each character is 4 bytes so to go to the next letter i need to increment the offset by four.
.data # Data declaration section
userString: .space 256
Prompt: .asciiz "\nEnter a word: "
newSpace: .asciiz " "
newLine: .asciiz "\n"
.text
main: # Start of code section
li $v0, 4
la $a0, Prompt
syscall
la $a0, userString
li $a1, 256
li $v0, 8
syscall
la $a0, userString
move $s0, $a0
loop:
lb $t1, 0($s0)
li $v0, 1
move $a0, $t1
syscall
li $v0, 4
la $a0, newSpace
syscall
addi $s0, $s0, 4
blt $s0, 256, loop
I've broken your code down into three parts: prompting, input, display. I assume the first two parts were given to you and the third is what you are focusing on right now. I'll explain what the first to parts are doing then explain what the third is doing right now and what you probably want it to do at this point.
.data # Data declaration section
userString: .space 256
Prompt: .asciiz "\nEnter a word: "
newLine: .asciiz "\n"
.text
# Part I
main: # Start of code section
li $v0, 4
la $a0, Prompt
syscall
# Part II
li $v0, 8
la $a0, userString
li $a1, 256
syscall
jr $ra
# Part III
la $a0, userString
move $t0, $a0
lb $t1, 0($t0)
li $v0, 4
move $a0, $t1
syscall # prints first letter of word
This is pretty straightforward, when we start executing the program counter will be set to the address of the main
label. It loads the value 4
into $v0
(that seems to be the print string system call number), and then loads the address of the Prompt
string into the first argument register $a0
. The last bit just performs the system call that puts the string on the screen.
Now that the "Enter a word: "
string has been printed on screen, we want to actually read what the user is typing. It looks like here we're using system call #8 (probably read string), so we load that value into $v0
in preparation for the syscall
. Then, since we want to read the user string into userString
, we load the address of that label into $a0
(the first argument for the read string function) then, since we are savvy programmers, we give the upper bound of how many bytes userString
can hold (256) in $a1
. Then we perform the system call, you type in a string at the keyboard and hit enter and we return to the next line of code.
That line is jr $ra
, which means "jump to the location stored in register $ra
(return address)". You probably don't want this, because it marks the end of the main function and likely you program exits back to the command line at this point, probably best to remove it.
Again, you're loading the address of userString
into $a0
(and also moving it into $t0
in the next line). Now it gets weird, you load the first byte 0($t0)
of userString
into $t1
. This is a ASCII character value (like 72 or something). Then you start up the system call stuff again with the print string system call (#4) and the argument of $t1
. Which you think will print the first letter of the word, which I disagree with. Here's why. If the user types the string, "Hello, world!" this is what it looks like in memory:
userString: H e l l o , w o r l d !
offset: 0 1 2 3 4 5 6 7 8 9 10 11 12
So, loading 0($t0)
moves the letter H
into register $t1
, then when you perform the system call it tries to print the string starting at H
to the screen. However, there is not a string starting at letter H
, it starts at the address of userString
. So if you just move the address of userString
into register $a0
, then do system call #4 it should print userString
to the screen.