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.
And finally, here's my code.
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!
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!