-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrc16-debug.asm
430 lines (364 loc) · 12.4 KB
/
crc16-debug.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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
%include "/usr/local/share/csc314/asm_io.inc"
segment .data
;data
test1 db "This is a test string",10,0
divisor dd 0xAC9A0000 ; common divisor value for CRC-16, claims to have HD of 8. padded with 0
test_filename db "asdf",0
;error
error_no_args db "usage: %s <file_name>",10,0
;info
mask db "Mask: ",0
xors db "XOR: ",0
shifts db "Shift: ",0
result db "Result: ",0
opened_file db "Opened file",10,0
print_fd db "File descriptor is %x",10,0
open_filename db "Opening '%s'",10,0
data_init db "Completed data init",10,0
check_bit db "Checking most significant bit...",0
print_mask db 9,"Mask value is ",0
check_bit_1 db "bit is 1",10,0
check_bit_0 db "bit is 0",10,0
exec_fill db "Filling mask from right",10,0
byte_read db 9,"Read byte from source",10,0
counter_val db 9,"Bit counter is %d",10,0
reached_eof db "Reached EOF",10,0
crc16_fmt db "CRC-16 value is: %x",10,0
finalizing db "Finalizing",10,0
segment .bss
segment .text
global asm_main
extern printf
asm_main:
push ebp
mov ebp, esp
; ********** CODE STARTS HERE **********
mov ecx, DWORD [ebp+8]
cmp ecx, 2
jne error_quit
mov eax, DWORD [ebp+12]
add eax, 4
mov eax, [eax]
push eax
call crc16_file
add esp, 4
jmp end
error_quit:
mov eax, DWORD [ebp+12]
mov eax, [eax]
push eax
push error_no_args
call printf
add esp, 8
mov eax, 1
int 0x1
end:
push eax
push crc16_fmt
call printf
; *********** CODE ENDS HERE ***********
mov eax, 0
mov esp, ebp
pop ebp
ret
crc16_file:
push ebp
mov ebp, esp
;-4 destination for bytes read from file
;-8 fd
;-12 counter for refill determination
;-16 space for reading more bytes from file
sub esp, 16
mov DWORD [ebp-4], 0
mov DWORD [ebp-8], 0
mov DWORD [ebp-12], 0
;open the file
push DWORD [ebp+8]
push open_filename
call printf
add esp, 8
mov eax, 0x5
mov ebx, DWORD [ebp+8]
mov ecx, 0
mov edx, 0
int 0x80
;store the fd
mov DWORD [ebp-8], eax
mov eax, opened_file ;Opened file
call print_string
push DWORD [ebp-8]
push print_fd
call printf
sub esp, 4
;read 4 bytes to initialize the data mask
mov eax, 0x3
mov ebx, DWORD [ebp-8]
lea ecx, [ebp-4]
mov edx, 4
int 0x80
;loop to calculate crc
;1. div must be aligned with most significant 1. shift if needed
;2. if there is a space of 8 on the right side of the mask, read another byte into it
;3. xor masked data with divisor
;4. loop until end of file
;5. keep xor'ing until mask is 0
;6. determine how much of divisor went past end of file, that is crc
;msb == most significant bit
start_check_loop:
mov eax, 1
shl eax, 31
and eax, DWORD [ebp-4]
cmp eax, 0
je shift
;if the msb is 1, xor the 16 msb with the divisor
;we can fall through to shift because we know the msb will now be 0
mov eax, mask
push DWORD [ebp-4]
call print_string
call print_binary
add esp, 4
mov eax, xors
call print_string
push DWORD [divisor]
call print_binary
add esp, 4
mov eax, [divisor]
xor DWORD [ebp-4], eax
mov eax, result
call print_string
push DWORD [ebp-4]
call print_binary
add esp, 4
call print_nl
;if the msb is 0, shift left once and increment the bit counter
;we fall through to fill in case we have gone through a whole byte
shift:
mov eax, mask
push DWORD [ebp-4]
call print_string
call print_binary
add esp, 4
shl DWORD [ebp-4], 1
inc DWORD [ebp-12]
mov eax, shifts
call print_string
push DWORD [ebp-4]
call print_binary
add esp, 4
call print_nl
;if the loop has gone through 8 bits, refill another byte
;this emulates a stream of data
fill:
cmp DWORD [ebp-12], 8
jl start_check_loop
mov DWORD [ebp-12], 0
mov eax, exec_fill
call print_string
mov eax, 0x3
mov ebx, DWORD [ebp-8]
lea ecx, [ebp-16]
mov edx, 1
int 0x80
cmp eax, 0
je near_eof
mov eax, DWORD [ebp-4]
mov ebx, DWORD [ebp-16]
mov al, bl
mov DWORD [ebp-4], eax
jmp start_check_loop
;continue xoring until [ebp-4 is 0]
;this means that entire input has benn zeroed
;increment the counter in each calculation
;counter tells us how many bits from the divisor make up the crc
near_eof:
;close the file, because we are good server cizitens
mov eax, 0x6
mov ebx, DWORD [ebp-8]
int 0x80
mov eax, reached_eof
call print_string
mov DWORD [ebp-12], 0
start_final_loop:
;mov eax, print_mask
;call print_string
;push DWORD [ebp-4]
;call print_binary
;add esp, 4
mov eax, DWORD [ebp-4]
cmp ax, 0
je final
;cmp DWORD [ebp-12], 32
;je final
mov eax, 1
shl eax, 31
and eax, DWORD [ebp-4]
cmp eax, 0
je shift2
mov eax, mask
push DWORD [ebp-4]
call print_string
call print_binary
add esp, 4
mov eax, xors
push DWORD [divisor]
call print_string
call print_binary
add esp, 4
mov eax, [divisor]
xor DWORD [ebp-4], eax
mov eax, result
call print_string
push DWORD [ebp-4]
call print_binary
add esp, 4
call print_nl
shift2:
mov eax, mask
push DWORD [ebp-4]
call print_string
call print_binary
add esp, 4
shl DWORD [ebp-4], 1
inc DWORD [ebp-12]
mov eax, shifts
call print_string
push DWORD [ebp-4]
call print_binary
add esp, 4
call print_nl
jmp start_final_loop
;now that we know we have <= the number of
; bit in the CRC, we can start shifting the XOR divisor
; instead of the mask of bits in the data
;This will also generate the final value
final:
mov eax, DWORD [ebp-4]
mov esi, 1
shl esi, 31
mov ecx, esi
mov edx, [divisor]
start_actual_final_loop:
cmp eax, 0
je end_actual_final_loop
and ecx, eax
cmp ecx, 0
je final_shift
push eax
mov eax, mask
push eax
call print_string
call print_binary
add esp, 4
mov eax, xors
call print_string
push edx
call print_binary
add esp, 4
pop eax
xor eax, edx
shr ax, 16
push eax
mov eax, result
call print_string
push eax
call print_binary
add esp, 4
call print_nl
pop eax
final_shift:
push eax
mov eax, mask
push DWORD edx
call print_string
call print_binary
add esp, 4
shr edx, 1
mov eax, shifts
call print_string
push DWORD edx
call print_binary
add esp, 4
call print_nl
pop eax
shr esi, 1
mov ecx, esi
jmp start_actual_final_loop
end_actual_final_loop:
mov ax, dx
mov esp, ebp
pop ebp
ret
;a debug funtion for printing a number as binary
;andrew you should make this a part of the functions in asm_io.inc
print_binary:
push ebp
mov ebp, esp
push edi
push esi
push edx
push ecx
push ebx
push eax
mov eax, DWORD [ebp+8]
mov ecx, 0
mov ebx, 2
start_bin_loop:
cmp eax, 0
je end_bin_loop
;cmp ecx, 32
;je end_bin_loop
mov edx, 0
div ebx
push edx
inc ecx
jmp start_bin_loop
end_bin_loop:
mov esi, 32
sub esi, ecx
mov edi, 0
start_bin_pad_loop:
cmp edi, esi
je end_bin_pad_loop
mov eax, 0
call print_int
inc edi
cmp edi, 8
je print_pad_space
cmp edi, 16
je print_pad_space
cmp edi, 24
je print_pad_space
jmp start_bin_pad_loop
print_pad_space:
mov eax, ' '
call print_char
jmp start_bin_pad_loop
end_bin_pad_loop:
start_bin_print_loop:
dec ecx
pop eax
call print_int
cmp ecx, 0
je end_bin_print_loop
cmp ecx, 8
je print_space
cmp ecx, 16
je print_space
cmp ecx, 24
je print_space
jmp start_bin_print_loop
print_space:
mov eax, ' '
call print_char
jmp start_bin_print_loop
end_bin_print_loop:
call print_nl
pop eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
mov esp, ebp
pop ebp
ret