MIPS assembly progr.-factorial calculation

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
4 replies · 7K views
electra123
Messages
4
Reaction score
0
I'm trying to write a MIPS assembly program that implements the calculation of n! Well i wouldn't be here if i were successful.When i try to run the following code on PCSpim this appears on the screen:
"Exception 6 [Bad instruction address] occurred and ignored"
Can anyone help me find my errors?i think my head is going to explode!

Thanks in advance...

Here is my code:

.data 0x10008000
.word 10
.word 1
.word 0
.ascii "The factorial of 10 is %d \n"
.text
.globl main

main:
addi $sp,$sp,-8
sw $ra,4($sp)
sw $fp,8($sp)
addiu $fp,$sp,4
lw $a0,4($gp)
jal fact

move $a1,$v0

jal printf
lw $ra,4($sp)
lw $fp,8($sp)
addi $sp,$sp,8
jr $ra

fact:
addi $sp,$sp,-8
sw $ra,4($sp)
sw $fp,8($sp)
addiu $fp,$sp,4
sw $a0,0($fp)

lw $v0,0($fp)

move $t0,$zero
slti $t0,$v0,1
beq $t0,$zero,L2
addi $v0,$zero,1
jr L1





L1:
lw $ra,4($sp)
lw $fp,8($sp)
addiu $sp,$sp,8
jr $ra

L2:
lw $v1,0($fp)
subu $v0,$v1,1
move $a0,$v0
jal fact
lw $v1,0($fp)
mul $v0,$v0,$v1


printf:
li $v0,4
la $a0,12($gp)
syscall

li $v0,1
move $a0,$v1
syscall
 
Physics news on Phys.org
Can you identify the line of code that causes the exception? There should be a debugger in PCSPIM that you can use to single-step through your code.

One thing that seems odd to me is that you have some data with no labels.
Here's some MIPS code that uses labels:
Code:
	.data 	0x10000100
first:		.word	0
last:		.word	0
mid:		.word	0
 
Well thank you very much for your respond but I've changed my code and now I'm facing a false result/calculation .I guess that in my previous program there was a problem with memory allocation in the stack.The reason i have these (.data 0x10008000 .word 10) is because i wanted for example to calculate 10!When I am running my new code though, i come up with an odd result(a very big obscure number)
i've been working on this new improved code for the last 8 hours with no results!Take a look if you want to help me.Thanks in advance :)
Here's my new code!
Code:
.data 0x10008000
.word 10
.word 1
.word 0
.ascii "The factorial of 10 is %d \n"
.text
.globl main

main:
                addi $sp,$sp,-32
	        sw $ra,20($sp)
                sw $fp,16($sp) 
                addiu $fp,$sp,28
	        lw $a0,0($gp) #$a0=10
	        jal fact
                
                add $a1,$v0,$zero
                
                jal printf

	        lw $ra,20($sp)
                lw $fp,16($sp)
	        addi $sp,$sp,32
	        jr $ra
               
fact:         
                addi $sp,$sp,-32
	        sw $ra,20($sp)
                sw $fp,16($sp) 
                addiu $fp,$sp,28
            
	        sw $a0,0($fp)
  
                lw $v0,0($fp)
	
                li $t0,1
                slti $t1,$v0,1
	        bne $t1,$t0,L2
	        addi $v0,$zero,1
                jr L1
		
L1:
                lw $ra,20($sp)
                lw $fp,16($sp)
                addiu $sp,$sp,32
                jr $ra

L2:
                 lw $v1,0($fp)
                 addi $v0,$v1,-1
                 add  $a0,$v0,$zero
                 jal fact
                 lw $v1,0($fp)
                 mul $v0,$v0,$v1                
                 
   
printf:
    
    li $v0,4
    la $a0,12($gp)
    syscall
    
    li $v0,1	
    add $a0,$a1,$zero
    syscall
 
Last edited:
electra123 said:
Well thank you very much for your respond but I've changed my code and now I'm facing a false result/calculation .I guess that in my previous program there was a problem with memory allocation in the stack.The reason i have these (.data 0x10008000 .word 10) is because i wanted for example to calculate 10!
I get it that you want to calculate 10!, but my question was, why aren't you using labels for your data values?
electra123 said:
When I am running my new code though, i come up with an odd result(a very big obscure number)
I tried running your code using QtSpim, which I believe is a more recent version.

So I wouldn't have to single-step through so much code, I changed the value from 10 to 3, which should return 6.

I don't know exactly what your problem is, but I can't figure out where you code is storing its computed values (that's where using labels for your data would be helpful!).

I get the same bogus value that you did, 2147482573, that is output in the last couple of lines of your printf routine.

Code:
    li $v0,1	
    add $a0,$a1,$zero
    syscall

Using the debugger, I see that the values in the relevant registers are as follows:
a0: 7ffffb2c
v0: 1 (this is the value for syscall to print an int)

It seems that you are loading a0 with an address rather than the value to print. If I check memory location 7ffffb2c, I see the value (as decimal) 2147482573.

For me, since I was calculating 3!, the code should have displayed 6, but I don't see that 6 has been stored anywhere.

I don't understand your algorithm well enough to follow what you're trying to do. I would strongly urge you to use the debugger so that you can figure out why you aren't getting the right value. For testing, try a smaller value. If you can revise your code so that it will calculate, say, 3!, it will likely work for 10! as well.
electra123 said:
i've been working on this new improved code for the last 8 hours with no results!Take a look if you want to help me.Thanks in advance :)
Here's my new code!
Code:
.data 0x10008000
.word 10
.word 1
.word 0
.ascii "The factorial of 10 is %d \n"
.text
.globl main

main:
                addi $sp,$sp,-32
	        sw $ra,20($sp)
                sw $fp,16($sp) 
                addiu $fp,$sp,28
	        lw $a0,0($gp) #$a0=10
	        jal fact
                
                add $a1,$v0,$zero
                
                jal printf

	        lw $ra,20($sp)
                lw $fp,16($sp)
	        addi $sp,$sp,32
	        jr $ra
               
fact:         
                addi $sp,$sp,-32
	        sw $ra,20($sp)
                sw $fp,16($sp) 
                addiu $fp,$sp,28
            
	        sw $a0,0($fp)
  
                lw $v0,0($fp)
	
                li $t0,1
                slti $t1,$v0,1
	        bne $t1,$t0,L2
	        addi $v0,$zero,1
                jr L1
		
L1:
                lw $ra,20($sp)
                lw $fp,16($sp)
                addiu $sp,$sp,32
                jr $ra

L2:
                 lw $v1,0($fp)
                 addi $v0,$v1,-1
                 add  $a0,$v0,$zero
                 jal fact
                 lw $v1,0($fp)
                 mul $v0,$v0,$v1                
                 
   
printf:
    
    li $v0,4
    la $a0,12($gp)
    syscall
    
    li $v0,1	
    add $a0,$a1,$zero
    syscall
 
Thank you very much for taking a look into this abysmal code :) i appreciate it!im going to work it again ,more serious this time!god...i hate assembly