• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Calling All Programmer and Tokkun - Spim/Assembly Help!!

Status
Not open for further replies.

mooooose

Member
My project is that I have to write a calculator in SPIM that will take the ASCII value of an expression, convert it to decimal, and print the answer. There is operator precedence so we're dealing with stacks.

I have three stacks, one for jumping addresses, one for operators, one for operands. If the stacks are empty and if the operator is of higher precedence than the one on the top of the stack, I push the operator and the operand before it to their stacks. If it's not greater, I do the operation on the top of the stack until the operation is of equal or lesser precedence, then push.

Right now, I can't even do 6+6. It just returns 6. After I run +6++6 (i use + or - in front of the number to determine its sign), there is a 6 at the top of the stack (I think its the 6 from the expression, somewhere my pointers are getting fucked) and here are all the values of my registers in decimal.


My code probably fucking sucks and I'm pretty shitty at coding in Assembly so I don't feel bad if anyone wants to give me any tips.

Code:
R0  [r0] = 0
R1  [at] = 268501116
R2  [v0] = 10
R3  [v1] = 0
R4  [a0] = 6
R5  [a1] = 32
R6  [a2] = 2147481740
R7  [a3] = 0
R8  [t0] = 5
R9  [t1] = 1
R10 [t2] = 10
R11 [t3] = 6
R12 [t4] = 10
R13 [t5] = 128
R14 [t6] = 31
R15 [t7] = 32
R16 [s0] = 6
R17 [s1] = 45
R18 [s2] = 43
R19 [s3] = 47
R20 [s4] = 42
R21 [s5] = 0
R22 [s6] = 0
R23 [s7] = 0
R24 [t8] = 0
R25 [t9] = 32
R26 [k0] = 0
R27 [k1] = 0
R28 [gp] = 268468224
R29 [sp] = 2147481728
R30 [s8] = 0
R31 [ra] = 4194428

And finally, here's my code.

Code:
	.text
	.globl main

main:
	li $t0, 0	#index parse string
	
	li $t1, 1	#pos=1/neg=0
	
	li $t2, 0	#holds parsed value
	li $t3, 0	#holds int
	li $t4, 10	#for multi and end
	
	li $t5, 128	#number stack pointer
	li $t6, 32	#op stack pointer
	li $t7, 32	#address stack
	
	li $t8, 0	
	li $t9, 32	#for reference
	
	li $s1, '-'
	li $s2, '+'
	li $s3, '/'
	li $s4, '*'
	li $s5, 0	#holds operator that doesn't go on stack yet
	li $s6, 0	#holds operator from top of stack
	
	li $v0, 8		#read string
	la $a0, string	#store string to memory
	li $a1, 32
	syscall
	
	jal calculate
	
	lw $s0, num($t5)
	addi $t5, $t5, 4
	
	move $a0, $s0
	li $v0, 1
	syscall
	
	li $v0, 10	#end
	syscall

calculate:
	addi $t7, -4
	sw $ra, address($t7)
calculate2:
	beq $t2,$t4,end2
	jal scan
	move $t3, $0
	j calculate2

scan:
	lb $t2, string($t0)
	addi $t0, 1
	beq $t2,$s2,scan2
	addi $t1, -1
scan2:
	lb $t2, string($t0)
	
	beq $t2,$s1,scan3		#signs
	beq $t2,$s2,scan3
	beq $t2,$s3,scan3
	beq $t2,$s4,scan3
	beq $t2,$t4,end		#end
	
	mult $t3, $t4
	mflo $t3
	addi $t2, -48
	add $t3, $t3, $t2
	
	addi $t0, 1
	
	j scan2					#continue loop until it hits a sign or end
scan3:
	beq $t1,$0,negative		#if negative, make negative, then jump back
	
	beq $t6,$t9,empty		#if stack is empty, jump
	
	lb $s6, string($t6)		#else, load top of stack
	#addi $t6, 1

	beq $t2,$s4,greater		#multiply always goes on stack
	beq $t2,$s3,divp
	beq $t2,$s2,addp
	beq $t2,$s1,subp
negative:
	not $t3, $t3
	addi $t3, 1
	addi $t1, 1
	j scan3

########################################################################
divp:
	move $t2, $s5
	beq $s6,$s4,lesser	#if top of *, lesser
	j greater			#else, greater
subp:
	move $t2, $s5
	beq $s6,$s2,lesser	#if top is +, lesser
	beq $s6,$s3,lesser	#if top is /, lesser
	beq $s6,$s4,lesser	#if top is *, lesser
	j greater			#else, greater
addp:
	move $t2, $s5			
	beq $s6, $s3,lesser	#if top is /, lesser
	beq $s6, $s4,lesser	#if top is *, lesser
	j greater			#else, greater
	
########################################################################
empty:
	addi $t6, $t6, -1 #load operator to stack
	sb $t2, op($t6)
	
	addi $t5, $t5, -4 #load number to stack
	sw $t3, num($t5)
	
	move $t3, $0 #clear t3

	jr $ra
	
greater:
	addi $t6, $t6, -1
	sb $t2, op($t6)
	
	addi $t5, $t5, -4
	sw $t3, num($t5)
	
	move $t3, $0

	jr $ra
	
lesser:
	lw $t8, num($t5)
	addi $t5, $t5, 4
	
	lb $s0, op($t6)
	addi $t6, $t6, 1
	
	addi $t6, $t6, -1
	sb $s7, op($t6)
	
	move $s7, $s0

	beq $s7,$s1,subtraction
	beq $s7,$s2,addition
	beq $s7,$s3,division
	beq $s7,$s4,multiplication

########################################################################
subtraction:
	sub $s0,$t8,$t3
	
	addi $t5, $t5, -4
	sw $s0, num($t5)
	
	move $t3, $0
	
	jr $ra
addition:
	add $s0,$t8,$t3
	
	addi $t5, $t5, -4
	sw $s0, num($t5)
	
	move $t3, $0
	
	jr $ra
division:
	div $t8,$t3
	
	mflo $s0
	addi $t5, $t5, -4
	sw $s0, num($t5)
	
	move $t3, $0
	
	jr $ra
multiplication:
	mult $t8,$t3
	
	mflo $s0
	addi $t5, $t5, -4
	sw $s0, num($t5)
	
	move $t3, $0
	
	jr $ra
########################################################################
end:
	addi $t5, $t5, -4 #load t3 into stack, then clear (makes sense so i can loop end2 multiple times until stacks are empty)
	sw $t3, num($t5)
	move $t3, $0
end2:
	beq $t7,$t9,end3 #if operator stack is empty, branch
	
	lw $t3, num($t5) #if not, load the two numbers on the stack and the operator
	addi $t5, $t5, 4
	
	lw $t8, num($t5)
	addi $t5, $t5, 4
	
	lb $s7, op($t6)
	addi $t6, $t6, 1
	
	
	beq $s7,$s1,subtraction #do operation
	beq $s7,$s2,addition
	beq $s7,$s3,division
	beq $s7,$s4,multiplication
end3:
	lw $ra, address($t7)
	addi $t7, 4
	jr $ra

.data
string:	.space 32
num:	.space 128
op:		.space 32
address:.word 32

I've been working on this on and off for the last couple days and it's now late... so I was wondering if GAF could help me out again? Thanks!
 
Status
Not open for further replies.
Top Bottom