How do I read a string from terminal input in Linux MIPS32 assembly? - linux

I'm currently learning MIPS programming in my university for the MARS simulator. However, I wanted to try to learn to write MIPS assembly programs for a MIPS Linux virtual machine. I managed to create a MIPS32 Debian 11 virtual machine. However, I having trouble with the Linux kernel system calls and their parameters. After some confusion, and a long time of searching the internet, I managed to create a basic hello world program. Then, I tried to create a program that would ask the user for some text, and then print it out, but it doesn't work.
I'm expecting something like this:
Please enter a string: This is text
The input is: This is text
However, I get:
Please enter a string: This is text
The input is:
My code is:
.data
prompt: .asciiz "Please enter a string: "
promptLength: .quad . - prompt
input: .space 81 #Create a 80-character empty string
inputLength: .word 80
answer: .asciiz "The input is: "
answerLength: .quad . - answer
newline: .asciiz "\n"
.text
.globl __start
__start:
#Display the prompt
li $a0, 1
la $a1, prompt
lw $a2, promptLength
li $v0, 4004
syscall
#Read the input
li $a0, 1
la $a1, input
lw $a2, inputLength
li $v0, 4003
syscall
move $s0, $v0
#Write the user input
li $a0, 1
la $a1, answer
lw $a2, answerLength
li $v0, 4004
syscall
la $a1, input
move $a2, $s0
syscall
#Exit
b exit
printNewline:
li $a0, 1
li $a1, newline
li $a2, 1
li $v0, 4004
syscall
jr $ra
exit:
li $v0, 4001
syscall
PS. Is there any book/YouTube tutorial/website that teaches MIPS programming for Linux?

Related

Separate words of the string and store them in stack in MIPS

.data
string: .asciiz "Please enter the string : "
newLine: .asciiz "\n"
buffer: .space 100
.text
.globl main
main:
la $a0, string
li $v0, 4
syscall
li $v0, 8
la $a0, buffer
li $a1, 100
syscall
la $t0, buffer
li $t0, 0
subu $sp, $sp, 4
li $v0, 4
syscall
Here above is beginning of the my code. And I need to separate each words of the string and then store them in the stack. First I tried to store word in stack as allocation memory with stack pointer and it works now. But I need to store each word(not characters) of the sentence such as
Hello I am Furkan
So for this example there should be 4 words in stack.
Hello
I
am
Furkan
How can I solve that ?

Can't write to file more than once in MIPS?

I'm currently trying to learn how to write to files, however I can't seem to write to a file more than once. How would I go about writing multiple strings to a file, or in this case, the same string more than once? Thanks.
.data
str_exit: .asciiz "test.txt"
str_data: .asciiz "This is a test!"
str_data_end:
.text
file_open:
li $v0, 13
la $a0, str_exit
li $a1, 1
li $a2, 0
syscall # File descriptor gets returned in $v0
file_write:
move $a0, $v0 # Syscall 15 requieres file descriptor in $a0
li $v0, 15
la $a1, str_data
la $a2, str_data_end
la $a3, str_data
subu $a2, $a2, $a3 # computes the length of the string, this is really a constant
syscall
move $a0, $v0 # Syscall 15 requieres file descriptor in $a0
li $v0, 15
la $a1, str_data
la $a2, str_data_end
la $a3, str_data
subu $a2, $a2, $a3 # computes the length of the string, this is really a constant
syscall
file_close:
li $v0, 16 # $a0 already has the file descriptor
syscall
I've been trying to figure this out for over half an hour yet the minute I post a question I figure it out on my own. I was setting $a0 to $v0, which had the incorrect value in it as I used $v0 after the first syscall, meaning I had the incorrect value in $a0 :\

MIPS - How do i concatenate User Input Strings and print them out after reading consecutive "\n" "\n"?

I have a function called saisir that needs to take in user input text and lets you enter \n 's in the input as part of the text. It returns the text that was entered by the user avec reading \n\n.
.data
buffer: .space 300
msg: .asciiz "You entered:\n"
.text
main: #calling the function
jal saisir
li $v0,10 #end the program
syscall
saisir:
li $v0,8 #take in input
la $a0, buffer #address where we store buffer
li $a1, 300
syscall
li $t0, 0
lb $t0, ($a0)
li $t1, 10 #\n caracter in ASCII
bne $t0, $t1, saisir
#Displays "You entered:"
li $v0, 4
la $a0, msg
syscall
#Displays User's input
li $v0, 4
la $a0, buffer
syscall
jr $ra #goes back
The code written right now overwrites every line of text entered by the user, therefore returns a string that is empty.. How to add the strings up as you would in a high level language with "+=" in MIPS?

MIPS - How to perform a shift on a string?

I'm very new to MIPS programming, and I've been stuck on a problem I've been attempting to program. I realize what I'm trying to do may be silly, but bear with me please! Here's a description of what I'm attempting to do.
Let's say that I have this string: "~~Hello World!". I want to obtain the string "Hello World!" by shifting this string left by two characters. So far, my closest attempt at performing such an operation is this:
Let the register $t0 contain the string "~~Hello World!". I want to perform a left shift of 2 bits on this string and store in the register $t1.
.data
output1: .asciiz "The value in $t1 is: "
.text
sll $t1, $t0, 2 # attempt at shifting left by 2 bits
li $v0, 4
la $a0, output1
syscall # print "The value in $t1 is: "
li $v0, 4
move $a0, $t1
syscall # print the contents of the register $t1
However, when I assemble these instructions, I'm met with an address out of range error. Can anybody point out where I'm going wrong, and perhaps what I should do to achieve this?
I've figured it out! Here is an updated code snippet, which now contains the working instructions. I'll leave this post up in case it helps anybody else.
.data
output1: .asciiz "The value in $t1 is: "
.text
add $t0, $t0, 2 # shifts the string left by 2 bits (CORRECT)
li $v0, 4
la $a0, output1
syscall # print "The value in $t1 is: "
li $v0, 4
move $a0, $t1
syscall # print the contents of the register $t1

MIPS, how to get 5 strings from console and then print them out

# Data section
.data
insert1: .word 20 # make space in memory for a word with address insert1
insert2: .word 20
insert3: .word 20
insert4: .word 20
insert5: .word 20
Input: .asciiz "Enter a Series of 5 formulae\n"
Output: .asciiz "The values are:\n"
CR: .asciiz "\n"
# Text Section
.text
.globl my_main
my_main:
la $a0, Input
li $v0, 4
syscall
la $a0, insert1 # sets $a0 to point to the space allocated for writing a word
la $a1, insert1 # gets the length of the space in $a1 so we can't go over the memory limit
li $v0, 8
move $t0, $a0
syscall
la $a0, insert2
la $a1, insert2
li $v0, 8
li $v0, 8
move $t1, $a0
syscall
la $a0, insert3
la $a1, insert3
li $v0, 8
li $v0, 8
move $t2, $a0
syscall
la $a0, insert4
la $a1, insert4
li $v0, 8
li $v0, 8
move $t3, $a0
syscall
la $a0, insert5
la $a1, insert5
li $v0, 8
li $v0, 8
move $t4, $a0
syscall
la $a0, Output
li $v0, 4
syscall
la $a0, insert1
li $v0, 4
syscall
la $a0, insert2
li $v0, 4
syscall
la $a0, insert3
li $v0, 4
syscall
la $a0, insert4
li $v0, 4
syscall
la $a0, insert5
li $v0, 4
syscall
# Exits Program
li $v0, 10
syscall
Results I'm getting:
Enter a Series of 5 formulae:
hey
man
how
are
you
The values are:
hey
man
how
are
you
man
how
are
you
how
are
you
are
you
you
Results I want:
Enter a Series of 5 formulae:
hey
man
how
are
you
The values are:
hey
man
how
are
you
So basically I need to take 5 strings from the console and then print out as seen above. Weirdly enough when I use words that are only 1 letter long it prints out correctly but anything else other than single letters returns a sequence of words similar to what I've shown above. I'm new to MIPS and not sure what I'm doing wrong here. Any help would be appreciated thanks.
EDIT: It seems I just needed to use .space instead of .word. Thanks to those who commented/answered the question for helping out.

Resources