MIPS Assembly Program Not Performing Lines - arrays

I am currently using MIPS Assembly. I have recently learned how to do both macros and arrays (of a sort), so I promptly wrote a fairly simple program to test them out. However, between getting the data and displaying it again, I wish to output a new message. For some reason, my program doesn't appear to do this, even though when running through it step by step it DOES, in fact, go through those lines - it just simply doesn't have any output. Is there any particular reason in MIPS Assembly why this isn't working, or is it a glitch in the MARS assembler?
.data
testlist: .word 50
request: .asciiz "Enter pi up to 50 digits: 3."
out: .asciiz "\nPi: 3."
.text
.macro arraygetword(%initaddress,%offset,%storeto)
la $a1,%initaddress
mul $a0,%offset,4
add $a0,$a0,$a1
lw %storeto,($a0)
.end_macro
.macro arraysetword(%initaddress,%offset,%value)
la $a1,%initaddress
mul $a0,%offset,4
add $a0,$a0,$a1
sw %value,($a0)
.end_macro
.macro arraygetbyte(%initaddress,%offset,%storeto)
la $a1,%initaddress
add $a0,%offset,$a1
lw %storeto,($a0)
.end_macro
.macro arraysetbyte(%initaddress,%offset,%value)
la $a1,%initaddress
add $a0,%offset,$a1
sw %value,($a0)
.end_macro
main:
la $a0,request
li $v0,4
syscall
li $t0,0
li $t1,50
forloop:
li $v0,12
syscall
arraysetword(testlist,$t0,$v0)# testlist[$t0]=$v0
addi $t0,$t0,1
blt $t0,$t1,forloop
li $t0,0
li $t1,50
la $a0,out# This is the part not working.
li $v0,4# Why doth this not output anything?
syscall# I need some sort of line break. It's awkward otherwise.
output:
arraygetword(testlist,$t0,$a0)# $a0=testlist[$t0]
li $v0,11
syscall
addi $t0,$t0,1
blt $t0,$t1,output
li $v0,10
syscall

testlist: .word 50 does not allocate 50 words, it allocates a single word with value 50. As such, your program is overwriting the memory after it, which contains your strings to print. Of course by that time you have already printed the request so that is not affected.

Related

MIPS assembly a simple for loop (2)

This is my 1st effort towards learning looping in MIPS.
.data
spc: .asciiz ", "
.globl main
main:
li $t0, 0
loop:
bgt $t0, 14, exit # branch if($t0 > 14)
addi $t0, $t0, 1 # $t0++ for loop increment
# print a comma
la $a0, spc # copy spc to $a0 for printing
li $v0, 4 # syscall value for strings
syscall
# repeat loop
j loop
exit:
li $v0, 10 # syscall value for program termination
syscall
Output:
-- program is finished running (dropped off bottom) --
This program is supposed to print 15 commas in the I/O console. That isn't taking place.
What could be the issue?
Ref: MIPS assembly for a simple for loop
You assembled all your code into the .data section; you never switched back to .text.
If you're using MARS, the GUI shows no asm instructions in the disassembly (after assembling). This is why.
Apparently instead of faulting on main being in a non-executable page, MARS simply decides that the program "dropped off the bottom" as soon as you start it.

MIPS: Storing integer input into memory using sw causes address out of range error

I am trying to store a dynamic array into a program using a stack, by first reading an input n and then creating a stack with [n] inputs. However, when I try to store word, it creates an error that I don't understand.
.data
ask_for_size: .asciiz "\nInsert the array size\n"
ask_for_int: .asciiz "\nInput number\n"
input: .space 16
.text
Main:
li $v0,4
la $a0,ask_for_size
syscall
li $v0,5
la $a0,input
syscall
add $t0,$v0,$zero
li $sp,0x00001000 #stack pointer
li $s0,0x00001000 #base pointer
la $a0,ask_for_int
Loop1:
li $v0,4
syscall
li $v0,5
syscall
sw $v0,0($sp)
addi $sp,$sp,-4
addi $t0,$t0,-1
bne $t0,$zero,Loop1
j Loop2
Loop2:
Shouldn't you add -4 to $sp before you sw $v0 into it?
addi $sp,$sp,-4
sw $v0,0($sp)
It seems to me that at this time you're overwriting past the end of $sp allocated for your process.
Also you load $a0 only once. Are you sure it does not get modified? Otherwise, maybe that would work better?
Loop1:
li $v0,4
la $a0,ask_for_int
syscall
...

Simple yes/no loop to repeat/end - MIPS assembly (MARS)

bI'm not so sure why it's not reading the input and deciding to repeat or end.. Here is my code, help would be appreciated!
.data
again:
.asciiz "Again (y or n)? "
answer:
.asciiz " "
.text
.globl main
main:
li $v0, 4
la $a0, again
syscall
la $s4, answer
jal get
beq $v0, 'y', main
beq $v0, 'Y', main
li $v0, 10
syscall
get:
li $v0, 12
li $a1, 2
syscall
jr $ra
Consider this:
.data
again:
.asciiz "Again (y or n)? "
answer:
.space 256
.text
.globl main
main:
li $v0, 4
la $a0, again
syscall
la $a0, answer
li $a1, 3
li $v0, 8
syscall
lb $t4, 0($a0)
beq $t4, 'y', main
beq $t4, 'Y', main
li $v0, 10
syscall
Firstly, in your code, you seem to misunderstand the way the syscalls work and how they ought to interact with functions (some docs here). Because your get routine basically just called a syscall, I took it out as adding a routine for something that basic is probably adding complexity rather than reducing it.
Next, the main problem of your code was a misunderstanding of the way input buffering works. In your code, you allocated exactly 2 bytes of space for answer, and then use syscalls to get no more than 2 bytes at a time. This will not work for stdin, because on most systems, stdin is line buffered, meaning that the user must press ENTER in order to flush the stream. This means that when the user types 'y', a syscall actually returns "y\n\0".
To fix this I expanded the syscall to read 3 characters and answer to store up to 256. Expanding this to be safe for any size is an excersize left to the reader.

Error Accessing Array in MIPS assembly

I made this code for finding LCM of two numbers. It is the starting chunk which is having problems. I tried to find the problem but couldn't figure it out. It is giving me error of unaligned address and other exceptions when I try to Load word or Store word. Here is the code:
.data
user: .asciiz "enter first number\n"
user2: .asciiz "enter second number\n"
array1: .space 500
array2: .space 500
array3: .space 500
.text
main:
la $a0,user
li $v0,4
syscall
li $v0,5
syscall
move $s0,$v0
la $a0,user2
li $v0,4
syscall
li $v0,5
syscall
move $s1,$v0
li $t0,0
li $t1,0
li $t2,2
li $t3,3
li $t4,0
li $t5,5
li $t6,7
li $t7,0
li $t8,0
li $t9,0
li $s8,0
la $t8,array1
la $t9,array2
j Loop1
Loop1:
div $s0,$t2
mflo $s2
mfhi $s3 # remainder
beq $s2,1,Loop2
xor $s5,$s3,$0
beq $s5,1,Odd3
add $t4,$t7,$t8
sw $t2,0($t4) # error
addi $t7,$t7,4
j Loop1
Regards
If it complains about unaligned address, then you should go look why it's unaligned. Assemblers are typically smart enough to align data as appropriate, but you are using the .space directive which doesn't have any type (and hence alignment) information. By chance your strings make the arrays unaligned. You can fix this by manually adding a .align 2 directive before array1.

How can I store sequence in an array in MIPS?

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

Resources