Could anyone please help me to figure out what causes my program to show Attempt to execute non instruction at 0x00400140, when I uncomment the beqz line. If I keep it commented my program runs just fine, but just as I uncomment it it shows the error at random times (i.e. sometimes after 5 seconds, sometimes after 10 seconds, etc). (The program is basically a timer and I am using beqz to only print once each second)
Any help would be greatly appreciated!
main:
addi $t0, $zero, 60 # stores 60 in $t0
div $s0, $t0 # divides total time by 60
mflo $s1 # stores minutes in $s1
mfhi $s2 # stores seconds in $s2
#beqz $s4, skip
#nop
move $s3, $ra # stores $ra in $s3
move $a0, $s1 # stores minute value in $a0
jal printToAscii # calls function to print minute
la $a0, colon # loads colon address in $a0
jal printColon # calls function to print colon
move $a0, $s2 # stores second value in $a0
jal printToAscii # calls function to print second
jal EraseLine
move $ra, $s3 # restores $ra
addi $s4, $zero, 0
skip:
j main
nop
Found the solution, my exception handler kept skipping the line so the j main line got skipped.
Related
so currently my code is just as shown below:
li $v0, 4 # printt first
la $a0, first
syscall
li $v0, 5 # receive input for first
syscall
add $s0, $v0, $zero # move first to s0
In a function, the arguments given contains a parameter block. In that parameter block the first two sections contain separate strings, and the third section will store the combined string. How do determine the address locations of the sections of the parameter block?
Perform Indexing or Indirect Addressing.
Here's an example:
.data
.align 2
problem1:
.word str_a1 # First number
.word str_a2 # Second number
.word buf_a # Place to store the result
.word 1 # Length of both numbers and result buf
.word out_a # Where to start printing the answer
.text
...
la $a0,problem # Address of parameters for
jal print_label # problem 1, and do it.
print_label:
...
move $s0, $a0 # copy the loc of the parm block to s0
li $v0, 4 # print 1st number
lw $a0, 0($s0)
syscall
li $v0, 4 # print 2nd number
lw $a0, 4($s0) # Indexing!
syscall
li $v0, 4 # print newline at end
la $a0, result3
syscall
The label representations are irrelevant. In essence the contents of $a0 are copied into $s0 and are accessed with indexing. If you were to increment its 'pointer' then that would be indirect displacement.
Perform whatever operations and they can be saved at a displaced location in the parameter block $a0 then read out as shown in the label problem1.
Using a simulator called MARS 4.5 I am trying to improve the cache performance of this code. This is a sub section of an assembly program that computes prime numbers using the Sieve of Eratosthenes algorithm.
For some reason the sw (store word) has a cache hit rate of 25% where the rest of the program is averaging at about 50% in it's current state. I've tried rearranging some things but I can't figure out what is causing this bottleneck. What needs to be done in order to improve this cache hit rate?
inner: add $t2, $s2, 0 # save the bottom of stack address to $t2
mul $t3, $t1, 4 # calculate the number of bytes to jump over
sub $t2, $t2, $t3 # subtract them from bottom of stack address
add $t2, $t2, 8 # add 2 words - we started counting at 2!
sw $s0, ($t2) # store 1's -> it's not a prime number!
add $t1, $t1, $t0 # do this for every multiple of $t0
bgt $t1, $t9, outer # every multiple done? go back to outer loop
j inner # some multiples left? go back to inner loop
I was able to fix this issue by modifying the program to store bytes instead of words. This increased the number of storage blocks in the cache and thus increased the hit rate.
inner: add $t2, $s2, 0 # save the bottom of stack address to $t2
addi $t3, $t1, 1 # add one byte
sub $t2, $t2, $t3 # subtract them from bottom of stack address
add $t2, $t2, 2 # add 2 bytes - we started counting at 2!
sb $s0, ($t2) # store 1's -> it's not a prime number!
add $t1, $t1, $t0 # do this for every multiple of $t0
bgt $t1, $t9, outer # every multiple done? go back to outer loop
j inner # some multiples left? go back to inner loop
I'm trying to sort a list of floating point integers in MIPS, which I think I'll be able to figure out, however, each of those float points corresponds to the score of a player in a game. I'm trying to figure out a way to remember that, for example, Bobby's score was 12.3, after I sort the floats in descending order, so that I could return something like:
"Bobby 12.3, Johnny 10.2, Carl 8.8".
Currently I'm storing the floats in the F registers as I read them in, and the names in a block of dynamically allocated memory whose size is generated based on how many players the user is considering.
.data
Prompt1: .asciiz "Please enter number of players.\n"
Prompt2: .asciiz "Please enter name of a player. (Max len 21 characters).\n"
Prompt3: .asciiz "Enter player's points per game.\n"
Prompt4: .asciiz "Enter player's minutes per game.\n"
numPlayers: .space 4
.text
.align 2
.globl main
main:
subu $sp, $sp, 32
sw $ra, 0($sp)
li $v0, 4
la $a0, Prompt1
syscall
li $v0, 5
la $a0, numPlayers
syscall
move $a0, $v0
jal collect
collect:
subu $sp, $sp, 32
sw $ra, 0($sp)
sw $a0, 4($sp)#number of players
addi $t1, $zero, 21 #21 is max length of player name in characters; 21 bytes
mult $t0, 4($sp), $t1 #number of bytes you're going to need for strings for x players
lw $a0, $t0 #a0 now has number of bytes you want for all of the strings
li $v0, 9
syscall
la $t2, $v0 #store memory allocated address into t2
la $t9, $t2 #remember the head you started at for strings
#memory has been made for strings
#make memory for floats now
addi $t0, $zer0, 32 #bits for a floating int, 1 calculation per player
mult $t0, $t0, 4($sp) #number of players times floating point space
lw $a0, $t0 #a0 now has number of bytes for all the floats
li $v0, 9
syscall
la $t8, $v0 #store memory allocated address into $t8 for floats
la $t7, $t8 #remember head you started at for floats
loop:
beq $t0, $zero, sort
la $a0, Prompt2 #print string asking for a player name
la $v0, 4
syscall
la $a0, $t2 #load address of huge memory space
la $a1, 21 #max characters to read is 21
la $v0, 8 #read string and store into address supplied by $a0
syscall
addi $t2, $t2, 21 #move up 21 places in the memory for t2
#so that you're sure you're at an empty space in memory for the next string
#time to read floats
#ask for the points per game
la $a0, Prompt3 #load string to ask points per game
li $v0, 4
syscall
li $v0, 6
syscall #f0 has the float
mov.s $f1, $f0 #f1 has points per game for player 1
la $a0, Prompt5 #load string to ask minutes per game
li $v0, 4
syscall
li $v0, 6
syscall #f0 has the float
mov.d $f2, $f0 #f2 has minutes per game
div.d $f3, $f1, $f2 #divide f1 by f2 store in f3
mov.d $t8, $f3 #t8 now has the points per minute for player
addi $t8, $t8, 32 #move up 32 spots in memory
#how to associate name and player?
addi $t0, $t0, -1 #decrement counter of how many more players you need to do
b loop
sort:
#to be figured out later
You can just do the same with the names as with the scores when you do the sorting, that is switching places, appending to a temporary list, etc.
That being said, it might be easier is you make a list of addresses for your names instead of all the names after each other. Thus, allocate a block of memory per name and store in the list. This way, sorting will be easier.
I have an assignment which is to write comb sort in MIPS. The user is going to enter the array and of course its size. When searching for heap allocation, I found the system call 9. However, I couldn't find the way to use it. I wrote this:
li $v0, 4
la $a0, message1 # prints the first message
syscall
li $v0, 5 # reads the size for the array
syscall
mul $t0, $v0, 4 # because array contains integer, I change them into bytes
la $a0, $t0 # allocate the size of the array in the heap
li $v0, 9 # now, $v0 has the address of allocated memory
syscall
move $v1, $v0 # Because systemcall uses $vo register, I move it to $v1 keep it safe.
create_array:
la $a0, message2 # prints the first message
li $v0, 4
syscall
li $s0, 0 # $s1 is the index, and loop induction variable
li $s1, 5 # $s1 is the sentinel value for the loop
Loop1:
bge $s0, $s1, End_Loop1
li $v0, 5 # Read integer values
syscall
mul $t3, $s0, 4 # $t3 is the offset
add $t4, $t3, $t0 # $t4 is the address of desired index
sw $v0, ($t4) # store the value in the array
addi $s0, $s0, 1 # increment the index
j Loop1
End_Loop1:
And I get this error:
la": Too few or incorrectly formatted operands. Expected: la $t1,($t2)
How can I use it? and Is this the right way to create an array?
Replace
la $a0, $t0 # allocate the size of the array in the heap
with
move $a0, $t0
The la instruction's purpose is to [L]oad the [A]ddress of a symbol into a register. For example:
la $a0, message1 # prints the first message
would load the address of message1 into register $a0. la is actually a pseudo-instruction which in this case translates into:
lui $a0, message1/0x10000 # load the upper halfword of the address
ori $a0, $a0, message1%0x10000 # OR in the lower halfword of the address
As you can imagine it doesn't make sense to try to load the address of another register, since registers don't have addresses.
While we're on the subject of MIPS pseudo-instructions: move is also one of them, and the above move $a0, $t0 instruction translates into something like add $a0, $0, $t0.
Also, replace $t0 with $v1. $t0 just holds the total byte allocated in the heap but you need $v1 which is the beginning addres of the array in the heap.
It should be like:
add $t4, $t3, $v1 # $t4 is the address of desired index