MIPS assembly progr.-factorial calculation

In summary: sw $fp,64($sp) addiu $fp,$sp,8 sw $a0,4($gp) lw $ra,4($sp) lw $fp,8($sp) addi $sp,$sp,8
  • #1
electra123
4
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
 
Technology news on Phys.org
  • #2
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
 
  • #3
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:
  • #4
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
 
  • #5
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
 

1. How do I calculate the factorial of a number in MIPS assembly?

To calculate the factorial of a number in MIPS assembly, you can use a loop to iterate through each number and multiply it by the previous number until you reach 1. You can store the result in a register and use it for further calculations or print it to the console.

2. What are the data types used in MIPS assembly for factorial calculation?

The data types used in MIPS assembly for factorial calculation are integers, which can be represented using the .word directive. MIPS assembly also supports floating-point calculations, which can be used for more complex factorial calculations.

3. How do I handle overflow when calculating factorials in MIPS assembly?

Overflow can occur when calculating factorials of large numbers in MIPS assembly. To handle this, you can check the size of the result after each multiplication and use conditional branching to handle the overflow and prevent data loss.

4. Can I use recursion to calculate factorials in MIPS assembly?

Yes, recursion can be used to calculate factorials in MIPS assembly. However, it is not the most efficient method and can lead to stack overflow if the number is too large. It is recommended to use iterative methods for factorial calculation in MIPS assembly.

5. How do I input a number from the user in MIPS assembly and use it for factorial calculation?

To input a number from the user in MIPS assembly, you can use the syscall for reading input and store it in a register. You can then use this register as the starting point for your factorial calculation. It is important to handle any potential errors with user input to ensure the program runs smoothly.

Similar threads

  • Programming and Computer Science
Replies
4
Views
1K
  • Programming and Computer Science
Replies
1
Views
8K
  • Programming and Computer Science
Replies
5
Views
9K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Programming and Computer Science
Replies
1
Views
14K
  • Programming and Computer Science
Replies
1
Views
7K
  • Programming and Computer Science
Replies
1
Views
7K
  • Programming and Computer Science
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
Back
Top