.data
EntryReq:
.asciiz "Please enter an 8 digit hexadecimal MIPS instruction: \n"
InputLongError:
.asciiz "\nYour input was too long, make sure it is 8 digits. "
InputShortError:
.asciiz "\nYour input was too short, make sure it is 8 digits. "
CharInvalidError:
.asciiz "\nYour input contains an invalid character. "
ValidChars:
.asciiz "0123456789abcdef\n\b\0"
.align 4
input:
.space 20
.text
main:
#Print input request
la $a0, EntryReq #loads input into arg. reg.
li $v0, 4 #op code for print string
syscall
#take input for input (stored)
li $v0, 8 #op code for take user input
la $a0, input #provide address for syscall
li $a1, 20 # tell syscall the byte space required for the string
syscall
#move to input(stored)
sw $v0, input #move inputted into from $v0 to input(stored)
#check validity of input
la $a0, input #load address of input to arg. reg. for method call
la $a1, ValidChars #load address of string of valid chars
jal verifyInput #call the verifyInput method which does as expected
#test if string length count works
addi $a0, $v0, 0 #load from $v0 to arg. reg.
li $v0, 1 #op code for print int
syscall
terminate:
li $v0, 10
syscall
verifyInput:
li $v0, -1 #start length count at 0
verifyLoop:
lb $t0, ($a0) #load current
li $a2, 0 #loop for char check, loops up to length of validChar string
la $a1, ValidChars
j checkChar
charVerified: #ignore this, is entry point back into verifyLoop for checkChar
addi $a0, $a0, 1 #increment
addi $v0, $v0, 1
bgt $v0, 8, printTooLongError #if result bigger than 8, error
bne $t0, 10, verifyLoop #10 is string end, so check if string is end
blt $v0, 8, printTooShortError #if result less than 8, error
jr $ra #if here string input was confirmed okay
checkChar: # loops through valid chars for each char in $a0 | Valid Chars: 0123456789abcdef\n |
lb $t1, ($a1) #loads in byte from char string
addi $a1, $a1, 1 #increment address, for the next char
addi $a2, $a2, 1 #increment until length of valid char string is reached
beq $t0, $t1, charVerified
bne $a2, 19, checkChar #if length of valid chars changes, change second argument here
j charNotValidError
charNotValidError:
la $a0, CharInvalidError #loads input into arg. reg.
li $v0, 4 #op code for print string
syscall
j terminate
printTooLongError:
la $a0, InputLongError #loads input into arg. reg.
li $v0, 4 #op code for print string
syscall
j terminate
printTooShortError:
la $a0, InputShortError #loads input into arg. reg.
li $v0, 4 #op code for print string
syscall
j terminate
The general gist of this code is for the user to input an 8 digit hexadecimal string, and then the program checks whether it is a valid hexadecimal string (i.e. includes only 0-9 and a-f). However, whenever I run it, the string that I input is missing the first four characters. So if I place invalid characters in the first four digits, like wwww1abc, then the code runs fine, which it shouldn't. But if I do 1abcwwww, it outputs an invalid character error, which it should. I'm genuinely confused as to why this is the case, nor have I seen anyone else experience this issue. Any help is greatly appreciated.
The problem is this line:
#move to input(stored)
sw $v0, input #move inputted into from $v0 to input(stored)
Unlike read integer syscall, read string puts the result in the input buffer, in your case input. So you don't need to read out the value in $v0 and by storing it in input you're overwriting the first 4 bytes of the buffer with the value of $v0, which is still 0x00000008, which conveniently is the same as the string "\b\0\0\0" for little endian machines, all of which are in your validity list. Removing that line should fix your program (though I didn't look over all the rest of the code for errors).
Related
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?
This seems like it should work but clearly doesn't. When I try to count the length of the string it returns some crazy long number. When I one step the program it works fine but prints out the wrong number. Can somebody point me back on track so that I can work on the next function? I just need to figure out what is throwing off the count
############################################
# Program Name: strings.s
# Programmer: David Bierbrauer
# Date: 9/07/2017
############################################
# Functional Description:
#
#
############################################
# Cross References:
#
#
############################################
.data # Data declaration section
stringa: .asciiz "Enter the first string: "
stringb: .asciiz "\nEnter the second string: "
.text
main: # Start of code section
#li $v0, 4 #get first string input
la $a0, stringa
jal read
jal length
jal print
#get second string input
la $a0, stringb
jal read
jal length
jal print
j end
length:
li $t0, -1 #loop count 0
j lengthloop
lengthloop: #exit address $s1
lb $t1, 0($a0) #load next char into $t1
beqz $t1, endlength
addi $a0, $a0, 1 #increment string pointer
addi $t0, $t0, 1 #increment count
j lengthloop
endlength:
jr $ra
equality:
lb $t2, 0($a0)
lb $t3, 0($a1)
bne $t2,$t3 notequal
append:
print:
li $v0, 1
la
syscall
jr $ra
read:
li $v0, 4
syscall #print prompt
li $v0,9
li $a0,80
syscall
move $a0,$v0
li $v0,8
li $a1,80
syscall
jr $ra
end:
li $v0, 10
syscall
The code you've posted doesn't even assemble, because there's a stray la in the print routine.
Aside from that, your length routine returns the length in $t0, while your print routine assumes that the value is in $a0. That's why you get the wrong output.
Your print looks odd. spim yells at me - bad syntax of la pseudoinstruction. I guess, you mean
print:
li $v0, 1
la $a0, 0($t0)
syscall
jr $ra
I'm trying to finish writing a mips palindrome function that "reads the same forward as backwards" and my function is not working as needed. This is hurting my brain and any help is greatly appreciated. Thank you!
A recursive definition of a palindrome is as follows:
Let the string S be represented as S = S1 S2 … SN, where N is the length of the string.
S is a palindrome
if N = 0 or N = 1 or
if N 2 and S1 = SN and the substring (S2 .. SN-1) is a palindrome.
Function Palin($a0, $a1)
Precondition:
$a0 holds the address of the first byte in the string (or substring) being tested while $a1 holds the length of the string (or substring)
Postcondition:
1 (true) is returned in the register $v0 if the given string (or substring) is a palindrome; otherwise, 0 (false) is returned in $v0.
.data
prompt1: .asciiz "Enter length of string to be read: "
prompt2: .asciiz "Enter the string "
ItIs: .asciiz "\nThe string IS a palindrome!"
IsNot: .asciiz "\nThe string is NOT a palindrome!"
string: .asciiz ""
.text
.globl main
main:
la $a0, prompt1
li $v0, 4
syscall
li $v0, 5
syscall
move $a1, $v0
la $a0, prompt2
li $v0, 4
syscall
addi $a1, $a1, 1
la $a0, string
li $v0, 8
syscall
addi $a1, $a1, -1
jal Palin
bne $v0, $zero, label1
la $a0, IsNot
j label2
label1:
la $a0, ItIs
label2:
li $v0, 4
syscall
li $v0 10
syscall
nop
Palin:
# HERE IS THE FUNCTION
li $v0, 10
syscall
addu $ra, $zero, $s7 #restore $ra since the function calles
#another function
jr $ra
add $zero, $zero, $zero
add $zero, $zero, $zero
EndPalin:
The problem is this:
Palin:
# HERE IS THE FUNCTION
li $v0, 10 # These
syscall # lines
The value 10 is the trap to exit the program and since you loaded that into register $v0 and then did a syscall, the program exits. Remove those offending lines and you should be on your jolly way.
HTH
Ok so I have an assignment where I have to find and print prime numbers.
I got that already complete, but now I need to print my results to a file.
Long story short, how do i print an integer to a file?
Long story
I can print integers and strings to the console, so I have my output like this:
1.) 2
2.) 3
3.) 5
...
I can print chars/strings just fine to a file, but all i can print is:
.)
.)
.)
....
Is there a way to convert or store an intger to a string in MIPS assembly? My assignment is not to do a MIPS version iota, so if there is a simple to just output an integer to file, I'd appreciate any insight.
I've read this page : MIPS File I/O Example
So that is how I learned to print strings to file, but i cannot find anything on how to print intgers that are calulated in the program. I've been looking since last night for an easy solution, but it escapes me.
This is the first MIPS assigment, we had to write a c program and then translate it to MIPS assembly, so I don't have too much experience so any help is appreciated.
Thanks in advance.
Here is the part of the code which I would like to work on, as you can see I'm trying to mirror what is desiplayed on the console in a text file. I'm using the MARS MIPS simulator.
FOR:
beq $t0, $t1, EndFOR
IF:
jal test_prime
bne $s1, 1, EndIF
addi $s0, $s0, 1 #Increment 'c'.
#Print 'c', the nth counted place of the found Prime Integer.
li $v0, 1
move $a0, $s0
syscall
sw $s0, buffer($0)
li $v0, 15
move $a0, $s7
la $a1, buffer
li $a2, 1
syscall
#Print '.) '
li $v0, 4
la $a0, dotP
syscall
li $v0, 15
move $a0, $s7
la $a1, dotP
li $a2, 3
syscall
#Print the Prime integer, 'i'.
li $v0, 1
move $a0, $t0
syscall
#Print a New Line.
li $v0, 4
la $a0, newL
syscall
li $v0, 15
move $a0, $s7
la $a1, newL
li $a2, 1
syscall
EndIF:
IF2:
beq $s0, 100, EndFOR #Once 100 Prime Integers have been found, escape out of the 'For' loop.
EndIF2: #Not Necessary, but just there to have a complete coding style.
addi $t0, $t0, 1 #Increment 'i'.
j FOR
EndFOR:
Assembly is all about appreciating high-level programming. You should try convert integer one by one to character and print them. You can turn this pseudo-code to assembly for this purpose (k is the integer number):
while(k){
char c = 0x03|((k%10)&0x0f);
push(c);
k=k/10;
}
while(c=pop()){
printf("%c",c);
}
In my MIPs Assembly Programming class I've been tasked with writing a program that converts a string into simplified pig latin.
Simplified pig latin assumes all words in the string are at least 2 characters long, and every word has its first letter shifted to the end followed by "ay". Also, assume there are no punctuation marks of any kind.
So, "stackoverflow is great" becomes "tackoverfloway siay reatgay".
I've taken a stab at this program and I'm nearly completed. It works fine, except that for some reason I have a line break in the middle of the last word every time.
For example:
tackoverflowsay siay reat
gay
Instead of:
tackoverflowsay siay reatgay
I've tried decuding what would be causing this line break in the last exit portion of my program but I don't see it. Do I have a pre-mature null terminated string? If I do, I don't see it.
Here is my code:
####################################################
# Text Segment
####################################################
.text
.globl main
main:
la $t0, char
la $t1, buffer
lb $t3, space
la $a0, prompt
li $v0, 4
syscall
la $a0, buffer
li $a1, 200
li $v0, 8
syscall
lb $t2, ($t1) # Load first char
addi $t1, $t1, 1
loop:
lb $t4, ($t1) # Load next character into $t4
addi $t1, $t1, 1
beqz $t4, exit # Reached end of string, exit?
beq $t3, $t4, loop2 # If $t4 = " " char, second loop
move $a0, $t4 # else, lets keep printing chars
li $v0, 11
syscall
j loop
loop2:
move $a0, $t2
li $v0, 11
syscall
la $a0, aystr
li $v0, 4
syscall
lb $t2, ($t1)
addi $t1, $t1, 1
j loop
exit:
move $a0, $t2
li $v0, 11
syscall
la $a0, aystr
li $v0, 4
syscall
li $v0, 10
syscall # Cya...
####################################################
# Data Segment
####################################################
.data
prompt: .asciiz "Enter Phrase: "
result: .asciiz "Pig Latin: "
space: .ascii " "
aystr: .asciiz "ay "
char: .byte 1
buffer: .byte 200
You almost certainly have a string of the form:
stackoverflow is great\n
where \n is a newline character. This would translate into:
tackoverflowsay siahy reat\ngay
if you simplistically detected the end of the word as either space or null-terminator.
I'm not going to give you the code (since this is homework) but the easiest solution, in my opinion, would be to have another loop processing the entire string, replacing all "\n" characters with spaces.
This would be done before your latinization loops.