我正在尝试用MIPS为我的Comp-Sci类手动构建一个计算器。我不是很远,因为我会通过我的代码看到,但我的主要问题是我的转换不起作用。当我输入一个数字时似乎很好,但是当我尝试输入像+或*这样的运算符时,它会存储疯狂的值,如" b" for +是11,而不是42.此外,它不能将我的输入键识别为十进制值为10的新行命令。
请让我直截了当?现在只有添加才能完全发挥作用,但在我能解决其他问题之前,我甚至无法证明这些问题能够起作用并转移到其他所有问题上。
.globl main
.globl done
.globl rdlp #read loop
.globl rdop #read operator
.globl stro #store operator
.globl strd #store digit
.globl chkd #check digit
.globl dig2 #10's digit
.globl dig3 #100's digit
.globl dig4 #1000's digit
.globl lp2d #10's digit loop
.globl lp3d #100's digit loop
.globl lp4d #1000's digit loop
.globl comp #computation loop
.globl chex
.globl chem
.globl chea
.globl adtn
.globl sbtr
.globl mulp
.globl mllp
.globl mul0
.globl mul1
.globl divi
.globl dvlp
.globl dv2a
.globl dv2b
.globl div3
.globl expo
.globl exlp
.globl excn
.globl exp0
.globl exp1
.globl modu
.globl molp
.globl mo2a
.globl mo2b
.globl mod3
.globl msrt
.globl srt1
.data
line: .asciiz "\n" #new line
#----------------------------------------------------
# Main body of the calculator
# reads string and converts
# from ascii
#
# s0 is main equation storage
# t0 is character storage
# t1 is boolean
# t2 is tens, 100's digit counter
# t3 is temp numerical storage
# t4 is temp storage
# t5 is counter for subtraction/mult/div
# t9 is loop counter for digits
#----------------------------------------------------
.text
main: lui $s0, 0x1000 #creates base address for storage
addi $s0, $s0, 4
rdlp: addi $v0, $0, 12 #empty prompt for calculator string entry
syscall
add $t0, $0, $0 #initialize t0 for loop sake
add $t0, $0, $v0 #dumps string into address of t0
add $t0, $t0, -48 #adjusts ascii value to decimal
beq $t0, 10, comp #moves out of read loop
j rdop
or $0, $0, $0 #no op
rdop: beq $t0, 94, stro
or $0, $0, $0
beq $t0, 37, stro
or $0, $0, $0
beq $t0, 42, stro
or $0, $0, $0 #no op
beq $t0, 43, stro
or $0, $0, $0
beq $t0, 45, stro
or $0, $0, $0 #no op
beq $t0, 47, stro
or $0, $0, $0 #no op
beq $0, $0, chkd
or $0, $0, $0 #no op
stro: bgtz $t2, strd #checks is a numerical digit is present
or $0, $0, $0
sw $t0, ($s0) #stores oprator into address in s0
addi $s0, $s0, 4 #increments address for next entry
j rdlp #jumps back to rdlp to
add $0, $0, $0 #increment operation counter
strd: sw $t3, ($s0) #adds value in t3 to store address
addi $s0, $s0, 4 #increments address for next value
add $t2, $0, $0 #initializes t2 to show no number
j stro #jump back to store operator
add $0, $0, $0 #increment operation counter
chkd: beq $t2, 1, dig2 #branches to 2dig to multiply by ten
or $0, $0, $0 #no op
beq $t2, 2, dig3 #addresses 100's position issue
or $0, $0, $0 #no op
beq $t2, 3, dig4 #addresses 1000's
or $0, $0, $0 #no op
add $t3, $0, $t0 #places digit value in t3 for temp
j rdlp #back to read loop
add $t2, $0, 1 #add 1 to digits count for 10's, 100's
dig2: add $t9, $0, 9 #add 9 to counter
lw $t1, ($s0)
add $t8, $0, $t1
lp2d: add $t1, $t1, $t8 #add t0 to itself and place in t0
add $t9, $t9, -1 #decrement counter
bne $0, $t9, lp2d #loop
add $t2, $t2, 1 #increment digit counter
add $t3, $t1, $t0 #adds 10's digit to value in t3 if any
add $t8, $0, $0
add $t1, $0, $0
j rdlp
add $t9, $0, $0 #reinitialize t9 counter
dig3: add $t9, $0, 99 #add 9 to counter
lw $t1, -4($s0)
add $t8, $0, $t1
lp3d: add $t1, $t1, $t8 #add t0 to itself and place in t0
add $t9, $t9, -1 #decrement counter
bne $0, $t9, lp3d #loop
add $t2, $t2, 1 #increment digit counter
add $t3, $t1, $t0 #adds 10's digit to value in t3 if any
add $t8, $0, $0
add $t1, $0, $0
j rdlp
add $t9, $0, $0 #reinitialize t9 counter
dig4: add $t9, $0, 999 #add 9 to counter
lw $t1, -9($s0)
add $t8, $0, $t1
lp4d: add $t1, $t1, $t8 #add t0 to itself and place in t0
add $t9, $t9, -1 #decrement counter
bne $0, $t9, lp4d #loop
add $t2, $t2, 1 #increment digit counter
add $t3, $t1, $t0 #adds 10's digit to value in t3 if any
add $t8, $0,$0
add $t1, $0, $0
j rdlp
add $t9, $0, $0 #reinitialize t9 counter
#----------------------------------------------------
# Section dealing with the calculator
# calculations and operators.
#----------------------------------------------------
comp: add $s2, $0, $s0 #saves address of final digit
lui $s0, 0x1000 #return to first address
addi $s0, $s0, 4 #increment mem address, 0 will store answers
chex: lw $a2, ($s0) #load possible operator into a2
beq $a2, 94, expo #branch to expo if ^ found
or $0, $0, $0
bne $s0, $s2, chex
addi $s0, $s0, 4 #increment address
lui $s0, 0x1000
addi $s0, $s0, 4
chem: lw $a2, ($s0) #load possible operator into a2
beq $a2, 42, mulp #branch to mulp if * found
or $0, $0, $0
beq $a2, 47, divi #branch to divi if / found
or $0, $0, $0
beq $a2, 47, modu #branch to modu if % found
or $0, $0, $0
bne $s0, $s2, chem
addi $s0, $s0, 4 #increment address
lui $s0, 0x1000
addi $s0, $s0, 4
chea: lw $a2, ($s0) #load possible operator into a2
beq $a2, 43, adtn #branch to adtn if + found
or $0, $0, $0
beq $a2, 45, sbtr #branch to sbtr if - found
or $0, $0, $0
bne $s0, $s2, chea
addi $s0, $s0, 4 #increment address
done: lui $s0, 0x1000
lw $a1, ($s0)
or $0, $0, $0
addi $v0, $0, 4
add $a0, $0, $a1
syscall
beq $0, $0,rdlp
#----------------------------------------------------
# the addition subroutine
#----------------------------------------------------
adtn: lw $a1, -4($s0) #add value left of operator in a1
lw $a3, 4($s0) #add value right of operator in a3
add $a1, $a1, $a3 #adds the values in a1 and a3
sw $a1, -4($s0) #store value into memory address
add $t8, $0, $s0 #add memory address to t8
lui $s0, 0x1000 #move focus back to first address
sw $a1, 0($s0) #store answer into first address
add $s0, $0, $t8 #restore original address focus
add $t8, $0, $0 #intialize t8
j msrt #jump to memory sorter
addi $s0, $s0, 4 #incremments memory
#----------------------------------------------------
# the substitution subroutine
#----------------------------------------------------
sbtr: sub $a1, $a1, $a3 #subtraction
#----------------------------------------------------
# the multiplication subroutine
# mllp is the actual loop for multiplying
# mul0 and mul1 deal with the cases of
# multiplying by 0 and 1.
#----------------------------------------------------
mulp: add $t5, $0, $a3 #begin multiplication set counter
beq $a1, 0, mul0 #event of mult by 0
or $0, $0, $0 #no op
beq $a3, 0, mul0 #event of mult by 0
or $0, $0, $0 #no op
beq $a1, 1, mul1 #event of mult by 1
or $0, $0, $0 #no op
beq $a3, 1, mul1 #event of mult by 1
or $0, $0, $0 #no op
mllp: add $a1, $a1, $a1 #begin multiplcation loop
add $t5, $t5, -1 #decrement loop counter
bne $t5, 1, mllp #branch when loop reaches 1
or $0, $0, $0 #no op
mul0: add $a1, $0, $0 #set value of zero due to mult by 0
mul1: add $a1, $0, $a1 #set value for mult by one
#----------------------------------------------------
# the division subroutine
# unchanged from my project 0 submission
#----------------------------------------------------
divi: add $t5, $0, 17 #set division loop counter
add $t3, $0, $a1 #set t3 to dividend from a1
add $t4, $0, $a3 #set t4 to divisor from a3
add $t6, $0, $a1 #set t6 to remainder which equals the dividend
sll $t4, $t4, 16 #shift the divisor left logical 16 places
dvlp: sub $t6, $t6, $t4 #subtracts divisor from remainder
bgez $t6 dv2a #if sub is greater than equal to zero branch
add $0, $0, $0 #NOP
bltz $t6 dv2b #branch if less than zero
add $0, $0, $0 #NOP
dv2a: sll $t7, $t7, 1 #logic shift left one zero to quotient
j div3 #moves calculation to third step
add $t7, $t7, 1 #add one to quotient
dv2b: add $t6, $t6, $t4 #restores value of remainder
j div3 #moves calculation to third step
sll $t7, $t7, 1 #shifts quotient left one bit and inserts zero
div3: srl $t4, $t4, 1 #shifts the divisor register one bit right
add $t5, $t5, -1 #decrements counter by one
bne $0, $t5, dvlp #loops back to division for next loop
or $0, $0, $0 #NOP
#----------------------------------------------------
# the exponent subroutine
#----------------------------------------------------
expo: add $t5, $0, $a1 #begin multiplication set counter
add $t6, $0, $a3 #exponent loop counter
add $t6, $t6, -1 #decrement power counter by 1 for first run
beq $a1, 0, exp0 #event of mult by 0
or $0, $0, $0 #no op
beq $a3, 0, exp0 #event of mult by 0
or $0, $0, $0 #no op
beq $a1, 1, exp1 #event of mult by 1
or $0, $0, $0 #no op
beq $a3, 1, exp1 #event of mult by 1
or $0, $0, $0 #no op
exlp: add $a1, $a1, $a1 #begin multiplcation loop
add $t5, $t5, -1 #decrement loop counter
bne $t5, 1, exlp #branch when loop reaches 1
or $0, $0, $0 #no op
excn: add $t6, $t6, -1 #decrement power loop
bgtz $t6, exlp
add $t5, $0, $a1 #branch delay reset mult counter
#placer for branch remember to zero out t5
exp0: add $a1, $0, $0 #set value of zero due to mult by 0
exp1: add $a1, $0, $a1 #set value for mult by one
#----------------------------------------------------
# the division subroutine
# unchanged from my project 0 submission
#----------------------------------------------------
modu: add $t5, $0, 17 #set division loop counter
add $t3, $0, $a1 #set t3 to dividend from a1
add $t4, $0, $a3 #set t4 to divisor from a3
add $t6, $0, $a1 #set t6 to remainder which equals the dividend
sll $t4, $t4, 16 #shift the divisor left logical 16 places
molp: sub $t6, $t6, $t4 #subtracts divisor from remainder
bgez $t6 dv2a #if sub is greater than equal to zero branch
add $0, $0, $0 #NOP
bltz $t6 dv2b #branch if less than zero
add $0, $0, $0 #NOP
mo2a: sll $t7, $t7, 1 #logic shift left one zero to quotient
j div3 #moves calculation to third step
add $t7, $t7, 1 #add one to quotient
mo2b: add $t6, $t6, $t4 #restores value of remainder
j div3 #moves calculation to third step
sll $t7, $t7, 1 #shifts quotient left one bit and inserts zero
mod3: srl $t4, $t4, 1 #shifts the divisor register one bit right
add $t5, $t5, -1 #decrements counter by one
bne $0, $t5, dvlp #loops back to division for next loop
or $0, $0, $0 #NOP
# placer remember the answer is the remainder t6
#----------------------------------------------------
# sort memory locations subroutine
#----------------------------------------------------
msrt: beq $s2, $s0, srt1 #branch to comp if memory is at last address
or $0, $0, $0
lw $a2, 4($s0) #load value into a2
sw $a2, -4($s0) #store a2 into earlier address
lw $a2, 8($s0) #load value into a2
sw $a2, ($s0) #store a2 into current address
or $0, $0, $0
j comp #jump back to comp
or $0, $0, $0
srt1: addi $s0, $s0, -8 #move memory address