-
Notifications
You must be signed in to change notification settings - Fork 0
/
lab42.asm
612 lines (536 loc) · 9.77 KB
/
lab42.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
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
assume cs: code, ds: data
initds macro
mov ax, data
mov ds, ax
endm
endprogram macro
mov ah, 4ch
int 21h
endm
print macro str
push ax
mov ah, 09h
lea dx, str
add dx, 2
int 21h
pop ax
endm
println macro str
print str
push ax
mov ah, 09h
lea dx, newline
int 21h
pop ax
endm
printchar macro char
push ax
push dx
mov ah, 2
mov dl, char
int 21h
pop dx
pop ax
endm
printdigit macro digit
push dx
mov dh, digit
add dh, '0'
printchar dh
sub dh, '0'
pop dx
endm
error macro message
println message
endprogram
endm
error_symbol macro message, symbol
print message
printchar symbol
endprogram
endm
scanstr macro string
mov dx, offset string
xor ax, ax
mov ah, 0Ah
int 21h
mov si, dx
xor bh, bh
mov bl, [si+1]
mov ch, '$'
add bx, 2
mov [si+bx], ch
mov dx, offset newline
mov ah, 09h
int 21h
endm
tostring macro num, output_string
push ax
push bx
push cx
push di
mov ax, num
mov di, 4
mov cx, 5
MOV BL,10
mov output_string[5], 10
mov output_string[6], 13
goto:
DIV BL
mov output_string[di], ah
add output_string[di],"0"
mov ah,0
sub di,1 ;di=di-1
loop goto
pop di
pop cx
pop bx
pop ax
endm
ifless macro a, b, endmark
cmp a, b
jge endmark
endm
ifequal macro a, b, endmark
cmp a, b
je endmark
endm
ifnotspace macro symbol, endmark
push ax
push bx
mov ah, ' '
mov bh, symbol
cmp bh, ah
pop bx
pop ax
je endmark
endm
ifnotend macro symbol, endmark
push ax
push bx
mov ah, '$'
mov bh, symbol
cmp bh, ah
pop bx
pop ax
je endmark
endm
ifflag macro flagname, endmark
push ax
push bx
xor ax, ax
mov bx, flagname
cmp bx, ax
pop bx
pop ax
je endmark
endm
ifnotnumber macro symbol, endmark
push ax
mov al, '/'
mov ah, '0'
add ah, notation
ifless symbol, ah, _&endmark
ifless al, symbol, _&endmark
pop ax
jmp endmark
_&endmark&:
pop ax
endm
ifnotminus macro symbol, endmark
push ax
push bx
mov ah, '-'
mov bh, symbol
cmp bh, ah
pop bx
pop ax
je endmark
endm
ifminus macro symbol, endmark
push ax
push bx
mov ah, '-'
mov bh, symbol
cmp bh, ah
pop bx
pop ax
jne endmark
endm
settrue macro flagname
mov flagname, 1
endm
setfalse macro flagname
mov flagname, 0
endm
movesymbol macro s1, s2
push ax
mov ah, s2
mov s1, ah
pop ax
endm
strlen macro str, reg
xor reg&x, reg&x
mov reg&l, str[1]
endm
;;;;;;
data segment
newline db 0Ah, "$"
string db 100, 99 dup ('$')
string1 db 100, 99 dup ('$')
max_len dw 16
num_a db 100, 99 dup (0) ; first num
num_b db 100, 99 dup (0) ; second num
num_c db 100, 99 dup (0) ; result
notation db 10 ; decimal or hex
cmpres db 0
error_wrong_symbol db 100, " error: non-numerical symbol $"
data ends
;;;;;;;;
code segment
tohex proc
mov cl, 60h
ifless cl, ch, tohexendif
sub ch, 'a'
add ch, ':'
tohexendif:
ret
tohex endp
fromhex proc
mov cl, '9'
ifless cl, ch, fromhexendif
sub ch, ':'
add ch, 'a'
fromhexendif:
ret
fromhex endp
numtostring proc
mov bp, sp
mov si, [bp + 2] ; num offset in di
mov ax, max_len
xor di, di ; di for indexing
add si, max_len
mov bl, [si]
cmp bx, 0
je plus
printchar '-'
jmp endsign
plus:
printchar '+'
endsign:
sub si, max_len
mov bx, 2
loop_numtostring:
mov ch, [si]
add ch, '0'
call fromhex
mov string[bx], ch
inc si
inc di
inc bx
ifless di, ax, break_numtostring
jmp loop_numtostring
break_numtostring:
ret
numtostring endp
printnum macro num
mov dx, offset num
push dx
call numtostring
println string
endm
tonum proc
mov bp, sp
mov di, [bp + 2]
strlen string, a
mov bx, max_len
sub bx, ax
add ax, 2
mov si, 2
xor dx, dx
mov [di], dx
loop_tonum:
mov ch, string[si]
call tohex
ifnotnumber ch, ok_it_is_number
ifnotminus ch, minus_case
error_symbol error_wrong_symbol, ch
ok_it_is_number:
jmp number_case
minus_case:
push ax
add di, max_len
mov ax, [di]
not ax
mov [di], ax
sub di, max_len
pop ax
jmp endcase
number_case:
sub ch, '0'
mov [di + bx], ch
endcase:
inc si
inc bx
ifless si, ax, break_tonum
jmp loop_tonum
break_tonum:
ret
tonum endp
invert_sign macro num
push di
push ax
mov di, max_len
mov al, num[di]
not al
mov num[di], al
pop ax
pop di
endm
swap_nums proc
push si
push ax
push bx
mov si, max_len
dec si
loop_swap:
mov al, num_a[si]
mov bl, num_b[si]
mov num_a[si], bl
mov num_b[si], al
dec si
cmp si, 0
je break_swap
jmp loop_swap
break_swap:
pop bx
pop ax
pop si
ret
swap_nums endp
compare_nums proc
push di
push ax
push bx
xor ax, ax
xor bx, bx
xor si, si
mov di, max_len
mov al, num_a[di]
mov bl, num_b[di]
cmp ax, bx
je loop_comp
jl sign_less
mov cmpres, 2
jmp endcompare_nums
sign_less:
mov cmpres, 1
jmp endcompare_nums
loop_comp:
mov al, num_a[si]
mov bl, num_b[si]
cmp ax, bx
je cmp_equal
jl equal_less
mov cmpres, 1
jmp break_comp
equal_less:
mov cmpres, 2
jmp break_comp
cmp_equal:
inc si
cmp si, max_len
jge break_comp
jmp loop_comp
break_comp:
; ; if signs - -
; mov di, max_len
; mov al, num_a[di]
; cmp al, 0
; jne endifcomp0
; xor ax, ax
; mov al, cmpres
; xor al, 11b ; 10 xor 11 = 01; 01 xor 11 = 10
; mov cmpres, al
; endifcomp0:
endcompare_nums:
pop bx
pop ax
pop di
ret
compare_nums endp
scannum macro num
scanstr string
mov dx, offset num
push dx
call tonum
endm
calculate_sum proc
; signes comp
mov di, max_len
mov al, num_a[di]
mov bl, num_b[di]
cmp al, bl
je skipdiff
invert_sign num_b
call calculate_diff
ret
skipdiff:
call compare_nums
cmp cmpres, 2
jne not_swap_
call swap_nums
invert_sign num_c
not_swap_:
mov di, max_len
mov al, num_a[di]
cmp al, 0
je invert_sign_in_diff_
invert_sign num_c
invert_sign_in_diff_:
mov si, max_len
sub si, 1
loop_sum:
xor cx, cx
mov ah, num_a[si]
mov bh, num_b[si]
mov ch, num_c[si]
add ch, ah
add ch, bh
mov cl, notation
dec cl
ifless cl, ch, sum_overflow
sub ch, notation
mov cl, 1
mov num_c[si - 1], cl
sum_overflow:
mov num_c[si], ch
dec si
cmp si, 0
jl break_sum
jmp loop_sum
break_sum:
ret
calculate_sum endp
calculate_diff proc
mov di, max_len
mov al, num_a[di]
mov bl, num_b[di]
cmp al, bl
je skipsum
invert_sign num_b
call calculate_sum
ret
skipsum:
call compare_nums
cmp cmpres, 2
jne not_swap
call swap_nums
invert_sign num_c
not_swap:
mov di, max_len
mov al, num_a[di]
cmp al, 0
je invert_sign_in_diff
invert_sign num_c
invert_sign_in_diff:
mov si, max_len
sub si, 1
xor dh, dh
loop_diff:
; put local diff in ch
xor cx, cx
mov ah, num_a[si]
mov bh, num_b[si]
add ch, ah
sub ch, bh
sub ch, dh
xor cl, cl ; cl <--- 0
xor dh, dh ; dh <--- 0
ifless ch, cl, diff_overflow
add ch, notation
mov dh, 1
diff_overflow:
mov num_c[si], ch
dec si
cmp si, 0
jl break_diff
jmp loop_diff
break_diff:
ret
calculate_diff endp
calculate_prod proc
mov di, max_len
sub di, 1
xor bx, bx
loop_sumprod:
mov si, max_len
sub si, 1
loop_prod:
xor ax, ax
xor cx, cx
xor dx, dx
mov al, num_a[si]
mov dl, num_b[di]
mul dx
mov cl, notation
div cl
sub si, bx
add num_c[si - 1], al
add num_c[si], ah
add si, bx
dec si
cmp si, 0
jl break_prod
jmp loop_prod
break_prod:
inc bx
dec di
cmp di, 0
jl break_sumprod
jmp loop_sumprod
break_sumprod:
mov di, max_len
sub di, 1
loop_fix:
; reminder in ch
xor ax, ax
mov cl, notation
mov al, num_c[di]
div cl
; add to next digit
add num_c[di - 1], al
mov num_c[di], ah
dec di
cmp di, 0
jl break_fix
jmp loop_fix
break_fix:
mov di, max_len
push ax
push bx
mov al, num_a[di]
mov bl, num_b[di]
xor al, bl
mov num_c[di], al
pop bx
pop ax
ret
calculate_prod endp
start:
initds
scannum num_a
scannum num_b
xor dx, dx
mov num_c[0], dh
; call calculate_sum
; call calculate_diff
call calculate_prod
; call compare_nums
; printdigit cmpres
printnum num_a
printnum num_b
printnum num_c
endprogram
code ends
end start