Skip to content

Commit 43d6f60

Browse files
authoredNov 13, 2021
계산기 만들기!
common.asm는 테스트 전용 comp411p1_2020112757.asm은 calc가 포함되어 있으며, 입출력 사칙연산 수행 (common.asm을 include하여 사용한다.)
0 parents  commit 43d6f60

File tree

2 files changed

+530
-0
lines changed

2 files changed

+530
-0
lines changed
 

‎common.asm

+255
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
# -------------------------------------------------------------------
2+
# [KNU COMP411 Computer Architecture] Test code for the 1st project (calculator)
3+
# -------------------------------------------------------------------
4+
5+
.data
6+
mul_str: .string "multiplication "
7+
add_str: .string "addition "
8+
sub_str: .string "subtraction "
9+
div_str: .string "division "
10+
success_str: .string "success counts:"
11+
total_testnum_str: .string "/100"
12+
.align 2
13+
14+
int_input1: .space 400 #reserve memory space to store the input values for the test
15+
int_input2: .space 400
16+
17+
18+
19+
.text
20+
##----------------------------------
21+
#name: init_test
22+
#func: initialize input values that will be used for test
23+
#----------------------------------
24+
init_test:
25+
addi t0, zero, 221 #1st operand
26+
addi t1, zero, 10 #2nd operand
27+
addi t2, zero, 100 #iteration count
28+
la t3, int_input1 #base address for 1st operand
29+
la t4, int_input2 #base address for 2nd operand
30+
init_test_loop:
31+
sw t0, 0(t3)
32+
sw t1, 0(t4)
33+
addi t0, t0, 1
34+
addi t1, t1, 1
35+
addi t3, t3, 4
36+
addi t4, t4, 4
37+
addi t2, t2, -1
38+
bne t2, zero, init_test_loop
39+
jalr zero, 0(ra)
40+
41+
42+
##----------------------------------
43+
#name: test_core
44+
#func: core procedure of basic functionality test
45+
#x10(a0): result
46+
#x11(a1): arithmetic operation (0: addition, 1: subtraction, 2: multiplication, 3: division)
47+
48+
#----------------------------------
49+
test_core:
50+
addi sp, sp, -88 #adjust stack pointer
51+
sw ra, 0(sp) #push register values to stack
52+
sw a0, 8(sp)
53+
sw a1, 16(sp)
54+
sw a2, 24(sp)
55+
sw a3, 32(sp)
56+
sw a4, 40(sp)
57+
sw a5, 48(sp)
58+
sw s0, 56(sp)
59+
sw s1, 64(sp)
60+
sw s2, 72(sp)
61+
sw s3, 80(sp)
62+
63+
#test for integer arithmetic
64+
addi s3, zero, 0 #test success count
65+
addi s0, zero, 100 #set the number of test
66+
la s1, int_input1 #store the base oddress array input1 in x6
67+
la s2, int_input2 #store the base oddress array input1 in x7
68+
69+
test_loop:
70+
lw a2, 0(s1) #load input1 to x12 (a2)
71+
lw a3, 0(s2) #load input2 to x13 (a3)
72+
73+
74+
addi t0, zero, 0
75+
bne a1, t0, get_answer_sub
76+
get_answer_add:
77+
add t1, a2, a3
78+
beq zero,zero, get_answer_done
79+
get_answer_sub:
80+
addi t0, zero, 1
81+
bne a1, t0, get_answer_mul
82+
sub t1, a2, a3
83+
beq zero,zero, get_answer_done
84+
get_answer_mul:
85+
addi t0, zero, 2
86+
bne a1, t0, get_answer_div
87+
mul t1, a2, a3
88+
beq zero,zero, get_answer_done
89+
get_answer_div:
90+
addi t0, zero, 3
91+
bne a1, t0, get_answer_done
92+
div t1, a2, a3
93+
rem t2, a2, a3
94+
95+
get_answer_done:
96+
jal ra, calc #call calc()
97+
bne a0, t1, test_done #check if the result of calc is correct
98+
addi s3, s3, 1 #increase the success count if the result is correct
99+
addi t0, zero, 3 #if the operation is division, check the remainer as well
100+
bne a1, t0, test_done
101+
beq a4, t2, test_done #decrease the success count if the remainder is not correct
102+
addi s3, s3, -1
103+
test_done:
104+
add a5, zero, s3 #store an argument (success count) in a5
105+
jal x1, print_test_message #call print_test_message
106+
addi x6, x6, 4 #increase base address of the array input1 by 4
107+
addi x7, x7, 4 #increase base address of the array input2 by 4
108+
addi s0, s0, -1 #decrease loop count
109+
addi s1, s1, 4 #increase the index for input1
110+
addi s2, s2, 4 #increase the index for input2
111+
bne s0, x0, test_loop
112+
113+
114+
lw ra, 0(sp) #pop register values from stack
115+
lw a0, 8(sp)
116+
lw a1, 16(sp)
117+
lw a2, 24(sp)
118+
lw a3, 32(sp)
119+
lw a4, 40(sp)
120+
lw a5, 48(sp)
121+
lw s0, 56(sp)
122+
lw s1, 64(sp)
123+
lw s2, 72(sp)
124+
lw s3, 80(sp)
125+
addi sp, sp, 88 #adjust stack pointer
126+
jalr zero, 0(ra)
127+
128+
##----------------------------------
129+
#name: test
130+
#func: functional test
131+
#x11: arithmetic operation (0:addition, 1: subtraction, 2: multiplication, 3: division)
132+
#x12: result calculated with the calc
133+
#----------------------------------
134+
test:
135+
addi sp, sp, -16
136+
sw a1, 0(sp)
137+
sw ra, 8(sp)
138+
139+
jal ra, init_test #initialize test inputs
140+
addi a1, zero, 0
141+
jal ra, test_core
142+
addi a1, zero, 1
143+
jal ra, test_core
144+
addi a1, zero, 2
145+
jal ra, test_core
146+
addi a1, zero, 3
147+
jal ra, test_core
148+
149+
lw a1, 0(sp)
150+
lw ra, 8(sp)
151+
addi sp, sp, 16
152+
153+
jalr zero, 0(ra)
154+
155+
156+
157+
158+
#----------------------------------
159+
#name: print_test_message
160+
#func: print a test message
161+
#x10(a0): result
162+
#x11(a1): arithmetic operation (0:int addition, 1: int subtraction, 2: int multiplication, 4: division)
163+
#x12(a2): 1st operand
164+
#x13(a3): 2nd operand
165+
#x14(a4): remainder
166+
#x15(a5): success count
167+
#----------------------------------
168+
print_test_message:
169+
addi sp, sp, -24
170+
sw a0, 0(sp)
171+
sw a1, 8(sp)
172+
sw a7, 16(sp)
173+
174+
add t2, a0, zero #store result in t2
175+
print_test_message_int_add:
176+
bne a1, zero, print_test_message_int_sub
177+
la a0, add_str
178+
addi t3, zero, 43 #store ascii code of operator in t3
179+
beq zero, zero, print_test_message_op
180+
print_test_message_int_sub:
181+
addi t0, zero, 1
182+
bne a1, t0, print_test_message_int_mul
183+
la a0, sub_str
184+
addi t3, zero, 45 #store ascii code of operator in t3
185+
beq zero,zero, print_test_message_op
186+
print_test_message_int_mul:
187+
addi t0, zero, 2
188+
bne a1, t0, print_test_message_int_div
189+
la a0, mul_str
190+
addi t3, zero, 42 #store ascii code of operator in t3
191+
beq zero,zero, print_test_message_op
192+
print_test_message_int_div:
193+
la a0, div_str
194+
addi t3, zero, 47 #store ascii code of operator in t3
195+
print_test_message_op:
196+
li a7, 4
197+
ecall
198+
199+
#print operation, operands, result
200+
li a7, 11
201+
li a0, 91 #display '['
202+
ecall
203+
li a7, 1
204+
addi a0, a2, 0 #display 1st operand
205+
ecall
206+
li a7, 11
207+
addi a0, t3, 0 #display operator
208+
ecall
209+
li a7, 1
210+
addi a0, a3, 0 #display 2nd operand
211+
ecall
212+
li a7, 11
213+
addi a0, zero, 61 #display '='
214+
ecall
215+
li a7, 1
216+
addi a0, t2, 0 #display result
217+
ecall
218+
addi t0, zero, 3
219+
bne a1, t0, print_success_cnt
220+
li a7, 11
221+
li a0, 44 #display ','
222+
ecall
223+
li a7, 1
224+
addi a0, a4, 0 #display remainder if the operation is division
225+
ecall
226+
print_success_cnt:
227+
li a7, 11
228+
li a0, 93 #display ']'
229+
ecall
230+
li a0, 44 #display ','
231+
ecall
232+
li a7, 1
233+
addi a0, t2, 0
234+
ecall
235+
la a0, success_str
236+
li a7, 4
237+
ecall
238+
li a7, 1
239+
add a0, zero, a5 #display the success count
240+
ecall
241+
li a7, 4
242+
la a0, total_testnum_str
243+
ecall
244+
245+
li a7, 11
246+
addi a0, zero, 10 #next line
247+
ecall
248+
249+
250+
lw a0, 0(sp)
251+
lw a1, 8(sp)
252+
lw a7, 16(sp)
253+
addi sp, sp, 24
254+
255+
jalr x0, 0(ra)

‎comp411p1_2020112757.asm

+275
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# -------------------------------------------------------------------
2+
# [KNU COMP411 Computer Architecture] Skeleton code for the 1st project (calculator)
3+
# 컴퓨터학부 2020112757 김유진
4+
# -------------------------------------------------------------------
5+
6+
.globl main
7+
8+
.data
9+
error_str: .string "error!"
10+
expr: .asciz ""
11+
.align 2
12+
.space 100
13+
14+
.text
15+
# main
16+
main:
17+
18+
jal x1, test #functionality test, Do not modify!!
19+
20+
#----TODO-------------------------------------------------------------
21+
#1. read a string from the console
22+
#2. perform arithmetic operations
23+
#3. print a string to the console to show the computation result
24+
#----------------------------------------------------------------------
25+
26+
addi sp, sp, -80
27+
sw s1, 0(sp)
28+
sw s2, 8(sp)
29+
sw s3, 16(sp)
30+
sw s4, 24(sp)
31+
sw s5, 32(sp)
32+
sw s6, 40(sp)
33+
sw s7, 48(sp)
34+
sw s8, 56(sp)
35+
sw s9, 64(sp)
36+
sw s10, 72(sp)
37+
38+
# input: get string from console
39+
la a0, expr
40+
li a1, 100
41+
li a7, 8
42+
ecall
43+
44+
addi t3, zero, 43 # '+'
45+
addi t4, zero, 45 # '-'
46+
addi t5, zero, 42 # '*'
47+
addi t6, zero, 47 # '/'
48+
49+
50+
# s1 -> 1바이트씩 읽어서 저장
51+
# s2 -> 첫 번째 operand를 위한 자릿수 counter
52+
# s3 -> 두 번째 operand를 위한 자릿수 counter
53+
# s4 -> 10의 n승!!
54+
# s5 -> 첫 번째 operand의 10의 자리 주소값 저장.
55+
# s6 -> 두 번째 operand의 10의 자리 주소값 저장.
56+
57+
# s7 -> a1 값 임시 저장
58+
# s8 -> a2 값 임시 저장
59+
# s9 -> a3 값 임시 저장.
60+
61+
# s10 -> '\n' 아스키코드 값
62+
li s10, 10
63+
64+
# a5 -> string의 원래 주소
65+
mv a5 a0
66+
67+
li s2, -1 # first counter -1로 초기화
68+
li s3, -1 # second counter -1로 초기화
69+
li s4, 10
70+
addi a1, zero, 2
71+
72+
oploop:
73+
lb s1, (a5) # 1바이트씩 읽어옴.
74+
addi a5, a5, 1 # pointer를 뒤로 한칸 옮김.
75+
beq s1, t3, addop #
76+
beq s1, t4, subop
77+
beq s1, t5, mulop
78+
beq s1, t6, dividop
79+
addi s8, s1, -48 # a2의 값을 임시로 s8에
80+
addi s5, a5, -2 # 이 주소를 읽으면 a210의 자리 숫자
81+
addi s2, s2, 1 # counter
82+
beq zero, zero, oploop
83+
84+
# s7(a1)에 부호값 넣기
85+
addop:
86+
addi s7, zero, 0
87+
beq zero, zero, setdone
88+
subop:
89+
addi s7, zero, 1
90+
beq zero, zero, setdone
91+
mulop:
92+
addi s7, zero, 2
93+
beq zero, zero, setdone
94+
dividop:
95+
addi s7, zero, 3
96+
97+
# second operand의 자릿 수 구하기.
98+
setdone:
99+
lb s1, (a5)
100+
addi a5, a5, 1
101+
addi a3, a3, 1
102+
beq s1, s10, second # \n문자 아스키 값 비교
103+
addi s9, s1, -48 # a3값을 임시로 s9에 저장 (마지막에 일의 자리 수가 저장됨.)
104+
addi s6, a5, -2 # 이 주소를 읽으면 a210의 자리 숫자
105+
addi s3, s3, 1 # counter
106+
beq zero, zero, setdone
107+
108+
# s9(a3)에 second operand 값 구해서 넣기.
109+
second:
110+
beq s3, zero, reset # second set complete
111+
lb s1, (s6) # 다음 자리 숫자 읽어옴. ###
112+
addi s1, s1, -48
113+
mv a2, s1
114+
mv a3, s4
115+
jal x1, calc # 계산
116+
add s9, s9, a0 # 곱한 값 더해주기.
117+
addi s3, s3, -1 # index - 1
118+
addi s6, s6, -1
119+
beq s3, zero, reset # second set complete
120+
mv a2, s4
121+
li a3, 10
122+
jal x1, calc
123+
mv s4, a0 # 0의 갯수 증가.
124+
beq zero, zero, second
125+
126+
reset:
127+
li s4, 10
128+
129+
# s8(a2)에 first operand 값 구해서 넣기.
130+
first:
131+
beq s2, zero, goout # second set complete
132+
lb s1, (s5) # 다음 자리 숫자 읽어옴.
133+
addi s1, s1, -48
134+
mv a2, s1
135+
mv a3, s4
136+
jal x1, calc # 계산
137+
add s8, s8, a0 # 곱한 값 더해주기.
138+
addi s2, s2, -1 # index - 1
139+
addi s5, s5, -1
140+
beq s2, zero, goout # second set complete
141+
mv a2, s4
142+
li a3, 10
143+
jal x1, calc
144+
mv s4, a0 # 0의 갯수 증가.
145+
beq zero, zero, first
146+
147+
# 결과 값 출력
148+
goout:
149+
mv a1, s7
150+
mv a2, s8
151+
mv a3, s9
152+
jal x1, calc
153+
li a7, 1
154+
ecall
155+
156+
# 나눗셈일 경우 나머지 출력
157+
li t0, 3
158+
bne a1, t0, exit # a13이 아니면 종료
159+
li a7, 11
160+
li a0, 44 # display ','
161+
ecall
162+
li a0, 32
163+
ecall # display ' '
164+
li a7, 1
165+
mv a0, a4 # display remainder
166+
ecall
167+
168+
lw s1, 0(sp)
169+
lw s2, 8(sp)
170+
lw s3, 16(sp)
171+
lw s4, 24(sp)
172+
lw s5, 32(sp)
173+
lw s6, 40(sp)
174+
lw s7, 48(sp)
175+
lw s8, 56(sp)
176+
lw s9, 64(sp)
177+
lw s10, 72(sp)
178+
addi sp, sp, 80
179+
180+
# Exit (93) with code 0
181+
exit:
182+
li a0, 0
183+
li a7, 93
184+
ecall
185+
ebreak
186+
187+
#----------------------------------
188+
#name: calc
189+
#func: performs arithmetic operation
190+
#x11(a1): arithmetic operation (0: addition, 1: subtraction, 2: multiplication, 3: division)
191+
#x12(a2): the first operand
192+
#x13(a3): the second operand
193+
#x10(a0): return value
194+
#x14(a4): return value (remainder for division operation)
195+
#----------------------------------
196+
calc:
197+
addi sp, sp, -24 #adjust stack pointer
198+
sw a2, 0(sp) # first
199+
sw a3, 8(sp) # second
200+
sw s0, 16(sp)
201+
202+
#TODO
203+
addi t0, zero, 0
204+
bne a1, t0, calc_sub
205+
206+
calc_add:
207+
add a0, a2, a3
208+
beq zero, zero, done
209+
210+
calc_sub:
211+
addi t0, zero, 1
212+
bne a1, t0, calc_mul
213+
neg a3, a3 # a3을 음수로 전환
214+
add a0, a2, a3
215+
beq zero, zero, done
216+
217+
calc_mul:
218+
addi t0, zero, 2
219+
bne a1, t0, calc_div
220+
addi t4, zero, 32 # index
221+
addi a0, zero, 0 # result (return value)
222+
mul_loop:
223+
andi t5, a3, 1 # LSB 구하기
224+
beq zero, t5, shift # 0 이면 바로 shift
225+
add a0, a0, a2 # a0에 multiplicand 더하기
226+
shift:
227+
slli a2, a2, 1 # multiplicand <<
228+
srli a3, a3, 1 # multiplier >>
229+
addi t4, t4, -1 # index 감소
230+
bne t4, zero, mul_loop # index가 0이 아니면 반복
231+
beq zero, zero, done
232+
233+
calc_div:
234+
beq a3, zero, error
235+
addi t4, zero, 17 # index
236+
addi a4, a2, 0 # initialize remainder (return value)
237+
addi a0, zero, 0 # quotient (return value)
238+
slli a3, a3, 16 # divisor << (initialized in the left half)
239+
div_loop:
240+
addi t5, a4, 0 # t5에 remainder 저장
241+
neg s0, a3
242+
add a4, a4, s0 # remainder = remainder-divisor
243+
blt a4, zero, recovery # remainder < 0 라면 recovery로
244+
slli a0, a0, 1 # (remainder >= 0) quotient << 1
245+
addi a0, a0, 1 # quotient + 1
246+
beq zero, zero, divisor_shift
247+
recovery:
248+
addi a4, t5, 0 # remainder = t5
249+
slli a0, a0, 1 # quotient << 1
250+
divisor_shift:
251+
srli a3, a3, 1 # divisor >> 1
252+
addi t4, t4, -1 # index 감소
253+
bne t4, zero, div_loop # index가 0이 아니면 반복
254+
255+
done:
256+
lw a2, 0(sp)
257+
lw a3, 8(sp)
258+
lw s0, 16(sp)
259+
addi sp, sp, 24
260+
261+
jalr zero, 0(ra)
262+
263+
# print error!
264+
error:
265+
la a0, error_str
266+
li a7, 4
267+
ecall
268+
269+
# Exit (93) with code 0
270+
li a0, 0
271+
li a7, 93
272+
ecall
273+
ebreak
274+
275+
.include "common.asm"

0 commit comments

Comments
 (0)
Please sign in to comment.