Mips programming jump problems - windows

Supposed to count number of R, I, and J instructions in the code starting from the first line in main. I have updated the code to all suggestions but results do not seem correct still. :(
EDIT: added those syntax changes, the variables seem to be working better, but the loop doesn't seem to be properly running through itself at all. Any noticeable problems anyone sees?
EDIT2: How do i change the loop to make $t1 rotate through 1 instruction set at a time? THAT is my key problem right now other than the silly syntax from a new mips user.
EDIT3: I have updated the code to all suggestions but results do not seem correct still. :(
.text
Main:
la $t1, 0x400000
li $t5, 0
li $t3, 2
li $t4, 3
li $t2, 0
la $s0, 0x400000
loop:
lw $t1, 0($s0)
addi $s0, 4
addi $t5, 1
beq $t5, 20 exit
srl $s4, $t1, 26
beq $s4, $t2 R
beq $s4, $t3 J
beq $s4, $t4 J
addi $s3, 1
j loop
R:
addi $s1, 1
j loop
J:
addi $s2, 1
j loop
exit:
sw $s1, RType
sw $s2, JType
sw $s3, IType
jr $ra

I see a set of problems:
1) Initialize the registers (don't assume register initial value is zero). For example, addi $t5, 1 requieres a previous add $t5, $zero, $zero (or li to the value you want).
2) the beq jump instruction requires two registers. For example, you have to change beq $s4, 3 J by:
li $t6, 3
beq $s4, $t6, J

In addition to Miguel's points I'd like to add that you're using the instruction set in a strange manner. Perhaps your assembler is capable of figuring out what you meant, but it's still makes the code confusing to read.
lw $t3, 2
lw $t4, 3
These should be li. The lw instruction is used for loading words from memory.
la $t0, 4($t1)
This should be lw, and unless you only want to check the instructions starting from address 0x400004 you should drop the offset.
I also can't seem to find anywhere where you increment $t1, so you'll be using the same address for every iteration of the loop.

Related

I'm getting an error which says MIPS: line 27: Runtime exception at 0x0040003c: address out of range 0x00000000. Don't really understand why

Write a MIPS assembly language program to count the number of occurrences of the lower-case "t" in a string. After running your code, the variable count (in memory) should contain the number of "t"'s in the string.
.text
.globl main
main: la $s1, strA
la $s2, count
lbu $s4, 0($s2)
add $s3, $zero, $zero
addi $t0, $zero, 116
add $t1, $zero, $zero
loop: lbu $s3, 0($s1)
addi $s1, $s1, 1
beq $s3, $t0, eqult
beq $s3, $zero, strgend
j loop
eqult: addi $t1, $t1, 1
j loop
strgend: sb $t1, 0($s4)
nop
.data 0x10010000
strA: .asciiz "the house on the left"
count: .byte 0

Changing ascending sort to descending in MIPS assembly

I know that in c or java the quick fix to changing an ascending sort to descending would be to find the < or > somewhere and reverse it. But try as I might, I can't find the equivalent (or equivalent swap) to change this code that I've written to be descending instead of ascending. (Right now, it works perfectly in printing the linkedlist in ascending order). There's a fair 100 or so lines above what I've included that I cut out as they don't do the sort, but they assign values--so that isn't the problem. I feel like I'm just missing something obvious? Would the change be in the way I print or the way I insert or both? Any help would be appreciated.
loop_to_find_correct_spot:
beqz $t0, if_current_node_next_equals_null
l.s $f0, 0($t0)
c.lt.s $f12, $f0
bc1t if_current_node_does_not_equal_null
or $t1, $t0, $zero
lw $t0, 4($t0)
j loop_to_find_correct_spot
if_current_node_next_equals_null:
# link this node to the previous, $v0 = &(previous node)
# copy address of the new node into the previous node
sw $v0, 4($t1)
# initalize the current node value to the passed in argument on the $f12 register
swc1 $f12, 0($v0)
# initalize the current node next value to null
sw $zero, 4($v0)
j end_insert_if_else
if_current_node_does_not_equal_null:
# initalize the current node value to the passed in argument on the $f12 register
swc1 $f12, 0($v0)
sw $v0, 4($t1)
sw $t0, 4($v0)
j end_insert_if_else
end_insert_if_else:
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
allocate_memory_for_node:
addi $sp, $sp, -4
sw $ra, 0($sp)
# allocate 12 bytes in memory for the new node
li $v0, 9
li $a0, 8
syscall
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
print_linked_list:
addi $sp, $sp, -4
sw $ra, 0($sp)
lw $s0, head # get a pointer to the head node
lw $s0, 4($s0)
begin_loop_print_linked_list:
# while (next != null)
beqz $s0, end_loop_print_linked_list
# get the value for the current node
l.s $f12, 0($s0)
# print out current item
li $v0, 2
syscall
la $a0, end_line_prompt #puts newlines in printed list
li $v0, 4
syscall
#get the pointer to the next node
lw $s0, 4($s0)
b begin_loop_print_linked_list
end_loop_print_linked_list:
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra

Assembly: how does this algorithm know when to stop

This is a pretty easy code, but i was wondering how this algorithm could know how to stop himself.
I mean, is there a way i can tell the program to stop when it reaches the end of the last array (forth) without using a "Branch equal to zero" in the loop section?
.data
first: .word 1,second
second: .word 2,third
third: .word 3,forth
forth: .word 4
.text
la $t1, first
lw $t2, 0($t1)
add $t4, $zero, $t2
j loop
loop:
addi $t1, $t1, 8
lw $t3, 0($t1)
add $t4, $t3, $t4
j loop
li $v0, 1
move $a0, $t4
syscall
li $v0, 10
syscall
Sorry for my bad english, and thank you :)

Trouble With Division Algorithm

I'm currently trying to code a function to divide integers in MIPS. I am supposed to use a division algorithm using this flowchart:
Here is the code that I have created:
.data
.text
main:
addi $a0, $0, 7
addi $a1, $0, 4
jal divide
addi $a0, $v1, 0
addi $v0, $0, 1
syscall
addi $v0, $0, 10
syscall
divide: # $a0/$s0 = Dividend-Remainder / $a1/$s1 = Divisor / $v1 = Quotient
# Initialize
addi $s0, $a0, 0
addi $s1, $a1, 0
addi $t0, $0, 0 # Counter = $t0
addi $t1, $0, 33 # Number of loops = $t1
# Start of loop
start:
# Step 1 : Subtract the divisor register from the remainder register and place in remainder register
sub $s0, $s0, $s1
# Step 2 : Test the remainder register. If < 0 go to part B, otherwise go to part A
addi $t3, $0, 0
slt $t2, $t3, $s0
beq $t2, $zero, partB
# Step 2A : Shift quotient register to the left, and make least significant bit 1
sll $v1, $v1, 1
ori $v1, $v1, 1
j after # Skip step 2B
# Step 2B : Add divisor to remainder and place sum in remainder register
partB:
add $s0, $s1, $s0
# Shift quotient register to left and make least significant bit 0
sll $v1, $v1, 1
after:
# Step 3 : Shift divisor right 1 bit
srl $s1, $s1, 1
# Increment counter
addi $t0, $t0, 1
# Test loop
bne $t0, $t1, start
jr $ra
I've been trying to catch my error but so far I have been unable to find it. When I run the code I get -1073741825 for the output.
Can someone check my logic and tell me what I'm doing wrong?

Printing to Screen in MARS for MIPS program

Hi I have to write a program in MIPS that does a bubble sort and then prints the sorted array and plays a note(s). I am having trouble getting it to execute in Mars and I am wondering what I need to add to my program:
.include "ec2_data.asm" # load values into array
add $s0, $zero, 0x10010000
add $t0, $zero, 0x10010000 #how many times to loop
addi $t1, $zero, 0 #initilize the counter
addi $t2, $zero ,0 #initilize position x
addi $t3, $zero, 4 #initilize position y
lw $s2, $t3($s0) #get second position of $s0=y
LOOP:
addi $t0, $t0, -1 #subtract one from the counter
slt $t4, $s1, $s2 #t4 set to 1 if x > y
beqz $t4, BREAK #if t0 is zero (x<y) we dont' have to sort, so go to break
# sort:
add $t5, $zero, $s1 #temp. stores the value of x in t5
add $s1, $zero, $s2 #moves the value of y into x
add $s2, $zero, $t5 #moves the value of x into y
sw $s1, $t2($s0) #save the new x to register
sw $s2, $t3($s0) #save the new y to register
j BREAK
BREAK:
#in here: check to see if we have reached the end
#if not, increment t2 and t3 by 4 to get the next values and jump back to loop to go again
beq $t0, $zero, END #if we are done with the array, go to end
addi $t2, $t2, 4
addi $t3, $t3, 4
j LOOP #jump back to loop again
END:
li $v0, 1 # print integer
syscall
addi $a0, $0, 0xA # load line code into register
addi $v0, $0, 0xB # print new line
syscall
addi $v0, $zero, 33 # midi out synchronous
addi $a0, $zero, 60 # Middle-C
addi $a1, $zero, 250 # ms
addi $a2, $zero, 120 # some instrument
addi $a3, $zero, 64 # some volume
add $a0, $t7, $zero # load value into $a0
syscall # play note!
addi $t6, $t6, 4 # shift memory location by 32 bits
addi $s1, $s1, 1 # increment counter ++
j loop # loop
Exit:
li $v0, 10 # load exit code
syscall # exit
If by "having trouble getting it to execute", you mean it acts strange with the .include file, then you might not have a required option checked in MARS. Go to the Settings menu and check the box for "Initialize Program Counter to global Main if defined". That seems to be something that has to be in effect for included files to work - and for some reason, it isn't turned on by default.

Resources