.data
equation : .space 256
equal : .string "="
error_msg : .string "incorrect operation !"
comma : .string ", "
# ------------------------------------------------------------------------------------
# [KNU COMP0411 Computer Architecture] Skeleton code for the 1st project (calculator)
# ------------------------------------------------------------------------------------
.text
# main
main:
jal x1, test #functionality test, Do not modify!!
#----TODO-------------------------------------------------------------
#1. read a string from the console
#2. perform arithmetic operations
#3. print a string to the console to show the computation result
#----------------------------------------------------------------------
jal ra, get_equation
mv t0, a0
addi t1, zero, 41
la t2, equation
lb a0, (t2)
li a7, 11
print:
ecall
addi t2, t2, 1
lb a0, (t2)
bge a0, t1, print
la a0, equal
li a7, 4
ecall
addi t1, zero, 1
mv a0, t0
beq x11, t1, signed
li a7, 36
beq zero, zero, unsigned
signed:
li a7, 1
unsigned :
ecall
addi t1, zero, 3
bne x11, t1, remainder
la a0, comma
li a7, 4
ecall
mv x10, x14
li a7, 1
ecall
remainder:
li a0, 0
li a7, 93
ecall
ebreak
get_equation :
# get equation
la a0, equation
li a1, 256
li a7, 8
ecall
addi sp, sp, -4
sw ra, 0(sp)
addi s10, zero, 1
slli s10, s10, 3
addi s10, s10, 2 # create 10
jal ra, get_first_int
jal ra, get_operation_symbol
lw ra, 0(sp)
addi sp, sp, 4
jalr zero, 0(ra)
get_first_int :
# get first integer
# result in x12
mv s8, ra
first_int_loop:
lb t0, (a0) # get 1 Byte from Memory
addi t0, t0, -48 # Sub ASCII code(0 == ASCII 48)
blt t0, zero, get_operation # if t0 < 0 (a1 is not integer) goto parse_equation
add s0, s0, t0 # s0 = s0 + t0
mv s9, x11
addi sp, sp, -8
sw a0, 4(sp)
sw s10, 0(sp)
mv x12, s0
mv x13, s10
jal ra, Mul
mv s0, a0
lw s10, 0(sp)
lw a0, 4(sp)
addi sp, sp, 8
mv x11, s9
#Mul s0, s0, s10 # s0 = s0 * s10(10)
addi a0, a0, 1 # a0 = a0 + 1 -> for get next ASCII
beq zero, zero, first_int_loop # loop
get_operation :
# if a1 is not integer -> operations
# result in x11
mv t3, zero
addi t0, t0, 48
addi t1, zero, 43
beq t0, t1, symbol
addi t1, zero, 45
addi t3, t3, 1
beq t0, t1, symbol
addi t1, zero, 42
addi t3, t3, 1
beq t0, t1, symbol
addi t1, zero, 47
addi t3, t3, 1
symbol:
mv x11, t3 # x11 is operation
mv s9, x11
addi sp, sp, -8
sw a0, 4(sp)
sw s10, 0(sp)
mv x12, s0
mv x13, s10
jal ra, Div
mv a7, a0
lw s10, 0(sp)
lw a0, 4(sp)
addi sp, sp, 8
mv x11, s9
#Div a6, s0, s10
addi a0, a0, 1
mv s0, zero
get_second_int :
# get second integer
# result in x13
lb t0, (a0) # get 1 Byte from Memory
addi t0, t0, -48 # Sub ASCII code(0 == ASCII 48)
blt t0, zero, equation_exit # if t0 < 0 (a1 is not integer) goto parse_equation
add s0, s0, t0 # s0 = s0 + t0
mv s9, x11
addi sp, sp, -8
sw a0, 4(sp)
sw s10, 0(sp)
mv x12, s0
mv x13, s10
jal ra, Mul
mv s0, a0
lw s10, 0(sp)
lw a0, 4(sp)
addi sp, sp, 8
mv x11, s9
#Mul s0, s0, s10 # s0 = s0 * s10(10)
addi a0, a0, 1 # a0 = a0 + 1 -> for get next ASCII
beq zero, zero, get_second_int # loop
equation_exit :
# get two integer and operation
mv s9, x11
addi sp, sp, -8
sw a0, 4(sp)
sw s10, 0(sp)
mv x12, s0
mv x13, s10
jal ra, Div
mv x13, a0
lw s10, 0(sp)
lw a0, 4(sp)
addi sp, sp, 8
mv x11, s9
#Div x13, s0, s10
mv x12, a7
mv ra, s8
jalr x0, 0(ra)
#----------------------------------
#name: calc
#func: performs arithmetic operation
#x11(a1): arithmetic operation (0: addition, 1: Subtraction, 2: Multiplication, 3: Division)
#x12(a2): the first operand
#x13(a3): the second operand
#x10(a0): return value
#x14(a4): return value (remainder for Division operation)
#----------------------------------
calc:
#TODO
get_operation_symbol :
#addi x11, x11, 42
mv t0, zero # 42 = *, 43 = +, 45 = -, 47 = /
beq x11, t0, add # if x11 < 44 -> x11 is * or +
addi t0, t0,1
beq x11, t0, Sub
addi t0, t0, 1
beq x11, t0, Mul
addi t0, t0, 1
beq x11, t0, Div
la a0, error_msg
li a7, 4
ecall
li a0, 0
li a7, 93
ecall
ebreak
add:
addi x11, zero, 0
add x10, x12, x13
jalr x0, 0(ra)
Sub:
addi x11, zero, 1
not x13, x13
addi x13, x13, 1
add x10, x12, x13
not x13, x13
addi x13, x13, 1
jalr x0, x1, 0
Mul:
addi sp, sp, -8
sw x12, 4(sp)
sw x13, 0(sp)
# mv s5, x12
# mv s6, x13
addi x11, zero, 2
mv x10, zero
mv t2, zero # control
addi t3, x0, 1 # iter count
addi t4, x0, 33 # max iter
addi t5, x0, 1 # LSB check
Mul_loop:
and t2, x13, t5
bne t2, t5, Mul_else
add x10, x10, x12
Mul_else:
slli x12, x12, 1
srai x13, x13, 1
addi t3, t3, 1
ble t3, t4, Mul_loop
lw x12, 4(sp)
lw x13, 0(sp)
addi sp, sp, 8
# mv x12, s5
# mv x13, s6
jalr x0, 0(ra)
Div:
mv s5, x12
mv s6, x13
addi sp, sp, -4
sw ra, 0(sp)
slli x13, x13, 16
addi t3, zero, 1 # iter count
addi t4, zero, 18 # max iter
mv t6, zero # Quotient
Div_loop :
jal x1, Sub # Dividend - Divisor
bge x10, zero, Div_else # if Remainder is grater or equal than 0, goto else -> Divide is true
add x10, x10, x13 # recover
beq zero, zero, Div_exit
Div_else:
ori t6, t6, 1
Div_exit:
slli t6, t6, 1
srli x13, x13, 1
addi x12, x10, 0
addi t3, t3, 1
blt t3, t4, Div_loop
mv x14, x10
srli t6, t6, 1
mv x10, t6
mv x12, s5
mv x13, s6
lw ra, 0(sp)
addi sp, sp, 4
addi a1, zero, 3
jalr x0, 0(ra)
.include "common.asm"