I am trying to create an integer array in MIPS wherein the user can choose the size and numbers that will be stored. For some reason, my program does not branch to the end loop when the array is full.
I apologize if the solution is glaringly obvious. This is homework, so I am not looking to plagiarize full code answers, but rather if I could be pointed towards the right direction I would appreciate it greatly. Thanks for looking.
.text
.globl __start # for PCSPIM //main for qtspim instead of __start
__start:
la $a0,pr1 # Ask user for amount of integers desired to be entered
li $v0,4 # a0 = address of string
syscall # v0 = 4, indicates display a string
li $v0,5 # Command to read an integer
syscall
sw $v0,count # Store int read into count
lw $t0,array # Point t0 to array
lw $t1,count # Point t1 to count
M_LOOP:
la $a0,pr2 # Prompt for integer
li $v0,4 # a0 = address of string
syscall # v0 = 4
li $v0,5 # Command to read an integer
syscall
beqz $v0, E_LOOP
sw $v0, array($t0) # Move the integer into the array
addi $t0,$t0,4 # Increment count by 4
sub $t1,$t1,1 # Subtract 1 from $t1
bnez $t0,M_LOOP
E_LOOP:
li $v0,10 # End Of Program
syscall # Call to system
.data
array: .space 100
pr1: .asciiz "Amount of integers to be entered: "
pr2: .asciiz "Integer to be inserted into array: "
newl: .asciiz "\n"
count: .word 0
Related
I've just started to learn MIPS, and as part of our assignment, I'm trying to save a counter value that runs inside a loop.
So, I was able to exit the loop, thanks to Michael. But now the counter will not increase, I noticed that it won't enter the incount label.
.text
.globl main
main:
# get string from user
la $a0, str1 # load the addr of the given string into $a0.
li $v0, 4 # 4 is the print_string syscall.
syscall # do the syscall.
li $v0, 8 # take in input
la $a0, buffer # load byte space into addr
li $a1, 10 # allot the byte space for the string
move $t0, $a0 # save the string into $to
syscall
# get char from user
la $a0, char1 # load the addr of the given char into $a0.
li $v0, 4 # 4 is the print_string syscall.
syscall # do the syscall.
li $v0, 8 # take in input
la $a0, buffer # load byte space into addr
li $a1, 10 # allot the byte space for the char
move $t1, $a0 # save the char into $t1
syscall
addi $s2, $zero,0 # s2 holds the counter
loop:
lb $t3, ($t0)
beq $t3, $t1, incount # go to incount if char was found
beqz $t3, exit # go to exit if we arrived to the end of the string
addi $t0, $t0, 1 # incrase t3 by 1
j loop # go to loop
incount:
addi $s2, $s2, 1 # increase the counter by 1
addi $t0, $t0, 1 # incrase char pos by 1
j loop # go back to loop
exit:
la $a0, ($s2) # counter to be printed
li $v0, 1 # 1 is the print_int syscall.
syscall
li $v0, 10 # return control to SPIM OS
syscall
.data
buffer: .space 10
str1: .asciiz "Please enter your string: "
char1: .asciiz "Now, please enter your char of choice: "
# end countchar.s
Thanks in advance
You've placed your exit routine in the .data section, which is why you're getting the "invalid program counter value" error message. All code needs to be in the .text section.
.data
prompt1: .asciiz "\n\n Enter an integer please:"
array: .space 24
linefeed: .asciiz "\n"
enterkey: .asciiz "Press any key to end program."
.text
main:
li $s0, 0
for:
bge $s0, 6, end_for
li $v0, 4 #syscall to print string
la $a0, prompt1 #address of string to print
syscall
li $v0, 5 #syscall to read an integer
syscall
move $t1,$v0
sw $t1,array($t0) #save the number to read into array
addi $t0,$t0,4
addi $s0,$s0,1
j for
end_for:
# print out a line feed
li $v0,4 # code for print_string
la $a0,linefeed # point $a0 to linefeed string
syscall # print linefeed
# wait for the enter key to be pressed to end program
li $v0,4 # code for print_string
la $a0,enterkey # point $a0 to enterkey string
syscall # print enterkey
# wait for input by getting an integer from the user (integer is ignored)
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
# All done, thank you!
li $v0,10 # code for exit
syscall # exit program
this is my code.I am trying to store 6 integers in an array and then read again the array of integers and sum them and then printing the sum.I apologize for my bad english
It would be basically the same loop you have just written, but instead of writing the number to the array you would have to read it from the array and sum the values.
E.g.:
li $s0, 0
li $a0, 0
li $t0, 0
forsum:
bge $s0, 6, end_forsum
lw $t1,array($t0) # Load the number from array
addu $a0, $a0, $t1 # Compute the sum
addi $t0,$t0,4
addi $s0,$s0,1
j forsum
end_forsum:
li $v0,1
syscall # Print sum
You can also compute the sum while reading the values from the user input...
.data
array: .word 0:5
prompt1: .asciiz "enter number: "
newline: .asciiz "\n"
.text
add $t2,$zero,$zero # initializes counter to 0
la $s0, array # stores the beginning of array into $s0
secretcode:
li $v0, 4 # prints "enter number: "
la $a0, prompt1
syscall
li $v0, 5 # reads in user input
syscall
sw $v0, ($s0) # saves user input into address at $s0
addi $s0, $s0, 4 # increments address at $s0 by 4 bytes
addi $t2, $t2, 1 # increments counter by 1
bne $t2, 5, secretcode # stops loop when loop executes 5 times
printsecretcode:
lw $a0, ($s0) # print first element
li $v0, 1
syscall
li $v0, 10 # system code halt
syscall
The program is supposed to store 5 user inputted numbers into an array. I tried to print the first value but it comes up as a large number which I assume is an address. How would I print the actual value of the number so that I know it saved correctly?
By the time you reach your printing code $s0 contains the address array + 4*5, so what you end up printing is the 32-bit number formed by the first four characters of the "enter number: " string.
To fix this, add an la $s0, array before you try to print the first element.
Overview of program: Input of a number 1-26, give the corresponding Capital letter too the number
My logic: Set up an Array type "structure" using .byte with chars. have a counter going through the array. once the counter is equivenlt to the input number print out the current point at the array.
This is a homework assignment so I'm not trying to "nudge" out the answer but guidance would be very helpful.
This is why where I think its going wrong. When I add 1 to the address it for some reason gives me a error. But when i add 4 it works fine? A char is supposed to take only 1 bit correct? I understand that when indexing address's of ints in an array it should be by 4.
.data
prompt: .asciiz "Enter the value of n here: "
larray: .byte 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
.globl main
.text
main:
la $t1, larray # Loads Array addresss into $t1
li $v0, 4 # System call for Print String
la $a0, prompt # Load address of prompt into $a0
syscall # Print the prompt message
li $v0, 5 # System call code for Read Integer
syscall # Read N into $v0
move $t3, $v0
li $t0, 0 # Loads int 0 into $t0
loop:
beq $t0, $t3, end # Break
lw $a0, ($t1) # Loads current pointer
addi $t0, $t0, 1 # Adds one to $t0 (Counting up +1)
addi $t1, $t1, 1 # Advances to next address in the array
j loop
end:
li $v0, 11 # Print at current index
syscall
li $v0, 10 # return control to system
syscall
I did do research on how to access the char a different way, but I don't think I can implement this way because you would need it hard coded?
Link:
This is the Stack Link that I found
There's no need for the array or the loop. If all you want to do is find the corresponding capital letter for a single number in the range 1-26, this would suffice:
li $v0, 5 # System call code for Read Integer
syscall # Read N into $v0
addiu $v0,$v0,'A'-1 # Convert the number 1-26 to the character 'A'-'Z'
A char is supposed to take only 1 bit correct?
One byte.
When I add 1 to the address it for some reason gives me a error. But when i add 4 it works fine?
You're using the lw instruction, which loads one word (4 bytes). To load a single byte, use the lb or lbu instruction (lb is for signed bytes, lbu for unsigned).
I have this homework problem .
Write a program that produces the following sequence; 1,2,2,4,8, 32, 256,… and stores it in an array, depending on the number of terms chosen by the user. Each element in the sequence can be calculated by multiplying the two elements preceding it. In other words the nth sequence number Sn is calculated by the equation Sn=Sn-1×Sn-2.
I tried but it didn't run
My code
^
^
# UNTITLED PROGRAM
.data # Data declaration section
str1: .ascii "Please enter the number of terms to produce: "
arr: .space 40
.text
main: # Start of code section
li $v0, 4 # system call code for printing string = 4
la $a0, str1 # load address of string to be printed into $a0
syscall # call operating system to perform print operation
li $v0, 5 # get ready to read in integers
syscall # system waits for input
move $s0,$v0 # store the result of the read (returned in $v0) in num1
la $s1,arr
addi $t2,$zero,2 # i=2
addi $t0,$zero,1
add $t1,$t0,$t0
sw $t0,0($s1)
sw $t1,0($s1)
L1:
addi $t2,$t2,1 #i++
addi $s1,$s1,4
lw $t4,0($s1) #A[i-1]
lw $t5,4($s1)
mul $t3,$t4,$t5
sw $t3,8($s1)
beq $t2,$s0,print
j L1
print:
lw $t3,0($s1)
li $v0, 1 # system call code for print_int
move $a0, $t3 # integer to print
syscall # print it
addi $s1,$s1,4
beq $t2,$s0,Exit
j print
Exit:
li $v0, 10 # exits program
syscall
# END OF PROGRAM
MARS error message:
Error in line 26: Runtime exception at 0x00400030:
store address not aligned on word boundary 0x1001002d
The error message is telling you that you're trying to access memory with an illegal (non word-aligned) address at this instruction:
sw $t0,0($s1)
When you have problems like this, you need to use the debugger. First, set a break point at the instruction where the exception is thrown.
Run the program, and when it stops at the break point, check the address (in $s1) you're trying to access. You'll see that it's 268501037 or 0x1001002d, and since it ends with a 7, it's not word-aligned.
$s1 has the correct array address, but I think you're assuming that when you created the array in the data segment, that it would start at a word-aligned address. This is not the case. To resolve this, you need to align the data.
.data # Data declaration section
str1: .ascii "Please enter the number of terms to produce: "
.align 2
arr: .space 40