Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Project: Simple Integer Calculator Given this modified definition of the stateme

ID: 3713372 • Letter: P

Question

Project: Simple Integer Calculator

Given this modified definition of the statement from the Compiler Modules grammar:

<assign> ::= Id = Int op Int

where Id = alphabetic variable name, 1 to 6 characters

Int = positive integer value < 1000

op = one of {+ add | - subtract | * multiply | / divide}

Write a correct program in MIPS - QtSpim assembly language that:

Interprets the statement from the grammar:

1) Accepts as input a string of up to 20 characters.

2) Parses the string according to the grammar.

3) Calculates the correct integer arithmetic result.

4) Writes the calculated result value to the QtSpim display screen.

Examples:

Input by the user : SUM = 123 + 751

Output of program: SUM = 874

Input by the user : total = 63 * 72

Output of program : total = 4536

Explanation / Answer

.data

# const string for welcome

welc: .asciiz "Welcome to SPIM Calculator 1.0! "

p_int: .asciiz " Please give an integer: "

p_op: .asciiz " Please give an operator: "

i_err: .asciiz " Input Incorrect, bad operator! "

again_str: .asciiz "Another calculation? (y/n)"

rmndr: .asciiz " r: "

new_line: .asciiz " "

int1: .word 1 # space to hold int 1

int2: .word 1 # space to hold int 2

raw_in: .space 1 # space to hold raw input

op: .space 1 # space to hold operator char

a_char: .space 1 # space to hold again char

out: .word 1 # space to hold output

remain: .word 1 # space to hold remainder

#operator constants

c_plus: .ascii "+" # const for +

c_min: .asciiz "-" # const for -

c_mult: .asciiz "*" # const for *

c_divi: .asciiz "/" # const for /

c_eq: .asciiz "=" # const for =

c_no: .asciiz "n" # const for n

.text

.globl main

main: li $v0, 4 # syscall 4, print string

la $a0, welc # give argument: string

syscall # actually print string

calc: la $t6, remain # load remainder variable

move $t6, $zero # store 0 in remainder (reset)

li $v0, 4 # syscall 4, print string

la $a0, p_int # give argument: string

syscall # actually print string

li $v0, 5 # tell syscall we want to read int 1

syscall # actually read in int 1

la $s1, int1 # load int1 into $s1

move $s1, $v0 # copy the integer from $v0 to int1

li $v0, 4 # syscall 4, print string

la $a0, p_int # give argument: string

syscall # actually print string

li $v0, 5 # tell syscall we want to read int 2

syscall # actually read in int 2

la $s2, int2 # give $s2 the address to hold int 2

move $s2, $v0 # copy the integer from $v0 to $s2

li $v0, 4 # syscall 4, print string

la $a0, p_op # give argument: string

syscall # actually print string

li $v0, 8 # tell syscall we want to read operator

la $a0, op # give $a0 the address to hold the operator

syscall # actually read in operator

lb $t0, op # load the first byte of op

li $t1, '+' # load const for plus

li $t2, '-' # load const for minus

li $t3, '*' # load const for multiplying

li $t4, '/' # load const for dividing

la $s0, out # load out to $s0

beq $t0, $t1, plus # we're adding

beq $t0, $t2, minus # we're subtracting

beq $t0, $t3, multi # we're multiplying

beq $t0, $t4, divi # we're dividing

# else

j error # incorrect input

plus: add $s0, $s1, $s2 # add our ints, store in $t0

j print

minus: sub $s0, $s1, $s2 # subtract our ints, store in $t0

j print

multi: slt $t1, $t2, $s2 # if our counter is less than int2, set $t1 to 1

beq $t1, $zero, print # if we've reached int2, we're done

add $s0, $s1, $s1 # add int1 and int1, store in out

j multi # loop

divi: la $t0 remain # load remainder into $t0

move $t0, $s1 # set remainder to dividend

add $s0, $zero, $zero # set out to 0, just in case

loop: slt $t1, $t0, $s2 # if remainder is less than divisor, set 1

beq $t1, $zero, print # if we're done branch to done

sub $t0, $t0, $s2 # sub divisor from remainder, store in remainder

addi $s0, $s0, 1 # increment quotient by 1

j loop # loop

print: li $v0, 1 # tell syscall we want to print int

la $a0, int1 # give syscall int1 to print

syscall # actually print int

li $v0, 4 # tell syscall we want to print string

lb $a0, op # tell syscall we want to print operator

syscall # actually print string

li $v0, 1 # tell syscall we want to print int

la $a0, int2 # give syscall int2 to print

syscall # actually print int

li $v0, 4 # tell syscall we want to print string

la $a0, c_eq # tell syscall we want to print operator

syscall # actually print string

li $v0, 1 # tell syscall we want to print integer

la $a0, out # give syscall our output

syscall # actually print int

la $t0, remain # load remainder

beq $t0, $zero, again # if we have no remainder, finish printing

li $v0, 4 # tell syscall we want to print string

la $a0, rmndr # tell syscall we want to print remainder string

syscall # print "r: "

li $v0, 1 # tell syscall we want to print int

la $a0, remain # give syscall our remainder to print

syscall # print remainder

again: li $v0, 4 # tell syscall we want to print string

la $a0, new_line # tell syscall to print new line

syscall

la $a0, again_str # load prompt for again string for syscall

syscall

li $v0, 8 # tell syscall we want to read string

la $a0, a_char # tell syscall to put it in $a0

syscall

lb $t0, a_char

li $t1, 'n' # get n char so we can compare

beq $t0, $t1, exit # if we are done, exit

#else loop

j calc # jump to beginning

error: li $v0, 4 # tell syscall we want to print string

la $a0, i_err # give syscall what to print

syscall # actually print

j again # go to prompt for retry

exit: li $v0, 10 # exit code

syscall #exit!