-
Notifications
You must be signed in to change notification settings - Fork 0
/
crc.asm
174 lines (121 loc) · 3.07 KB
/
crc.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# CRC Checksum calculation in risc-V
# Inspired by: https://dvsoft.developpez.com/Articles/CRC/
.data
buffer: .asciz "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
buffer_size: .word 100
# CRC16-CCITT Specific
crc_polynomial: .word 0x1021
crc_init_value: .word 0xFFFF
str_1: .asciz "String 1: "
str_2: .asciz "String 2: "
str_equal: .asciz "Strings are equal! :D"
str_not_equal: .asciz "Strings are not equal! :("
str_new_line: .asciz "\n\n"
str_checksum_1: .asciz "Checksum 1: "
str_checksum_2: .asciz "Checksum 2: "
.text
.macro process_byte # params: a0 = current byte / t0 = checksum
la s3, crc_polynomial # polynomial address
lw s4, 0(s3) # polynomial
slli s4, s4, 8 # create 8 empty bits on right
li s5, 8 # iterator (init value: byte size)
slli t0, t0, 8 # create 8 empty bits on right
add t0, t0, a0 # add input byte to checksum
byte_for:
beqz s5, end_byte_for # if i == 0, break for loop
slli t0, t0, 1 # move 1 bit to left
mv s6, t0 # temp copy of checksum. Goal: find the 25th bit's value (from 32 bits)
slli s6, s6, 7 # move 7 bits to left
srli s6, s6, 31 # move 31 bits to right
beqz s6, end_update_checksum # if bit == 0, do NOT update checksum
update_checksum:
xor t0, t0, s4 # checksum ^ polynomial
end_update_checksum:
addi s5, s5, -1 # i--
j byte_for
end_byte_for:
slli t0, t0, 8 # delete 8 bits on the left
srli t0, t0, 16 # delete 16 bits on the right
.end_macro # return: t0 = checksum
.macro process_string # params: NO
la s0, buffer # buffer address
la s1, buffer_size # size address
la s2, crc_init_value # init value address
lw t0, 0(s2) # checksum (default value)
lw t1, 0(s1) # size
li t2, 0 # iterator
li a7, 8 # read str string
mv a0, s0 # set buffer
mv a1, t1 # set max number of char
ecall
string_for:
beq t1, t2, end_string_for # if i > size, break for
lb a0, 0(s0) # load char from buffer
li t3, '\n' # null terminator
beq a0, t3, end_string_for # if end of string, break for
process_byte # process char in a0
addi s0, s0, 1 # move to next char address
addi t2, t2, 1 # i++
j string_for
end_string_for:
li a0, 0x00
process_byte # process char in a0
li a0, 0x00
process_byte # process char in a0
mv a0, t0
.end_macro # return: a0 = checksum
########
# MAIN #
########
## VAR
li s10, 0 # str_1 checksum
li s11, 0 # str_2 checksum
## STR 1
li a7, 4 # print first message
la a0, str_1
ecall
process_string # call macro
mv s10, a0 # save str_1 checksum
## STR 2
li a7, 4 # print second message
la a0, str_2
ecall
process_string # call macro
mv s11, a0 # save str_2 checksum
## COMPARE & PRINT
# new line
li a7, 11
li a0, '\n'
ecall
beq s10, s11, is_equal
li a7, 4
la a0, str_not_equal
ecall
j end_is_equal
is_equal:
li a7, 4
la a0, str_equal
ecall
end_is_equal:
# new line
li a7, 4
la a0, str_new_line
ecall
li a7, 4 # print first checksum message
la a0, str_checksum_1
ecall
# print first checksum
li a7, 1
mv a0, s10
ecall
# new line
li a7, 11
li a0, '\n'
ecall
li a7, 4 # print second checksum message
la a0, str_checksum_2
ecall
# print second checksum
li a7, 1
mv a0, s11
ecall