-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprog_1.asm
191 lines (183 loc) · 4.21 KB
/
prog_1.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
.model small
.stack 24 ;bytes, 10 - word - stack depth for func_uint32OUT, 2 - for funclion call
.data
;Constants
msg_enterM_err db 0Ah,'"m" must be above "n"! '
msg_enterM db 0Ah,'Enter "m": $'
msg_enterN_err db 0Ah,'"n" must be above or equal 0! '
msg_enterN db 'Enter "n": $'
msg_result db 0Ah,'Result: $'
msg_calc_error db 0Ah,'The result is too big!',0Ah,'Further calculation is not possible.$'
func_uint16IN_errmsg db 0Ah,'Invalid input! Enter 16-bit unsigned number: $'
func_div32x16_divider dw 10
;Multithread non-safe
func_uint16IN_buffer db 6, 0, 6 dup(?)
.code
start proc
mov ax, @data
mov ds, ax ;init data segment
lea dx, msg_enterN
N_reenter:
mov ah,9
int 21h ;message print
call func_uint16IN ;input number
test ax,ax
jz N_unc
mov di,ax ;di = n
lea dx, msg_enterM
M_reenter:
mov ah,9
int 21h ;message print
call func_uint16IN ;input number
cmp ax,di
jb M_unc
je N_decrease
next1:
xor dx,dx ;dx - result high word
sub di,1
jbe displ_result ;jump to skip loop
mov cx,di
mov bx,ax ;bx = m, ax - result low word
cloop:
dec bx
call func_mul32x16
jc calc_error
loop cloop
displ_result:
mov bx,ax
mov cx,dx ;save registers values
lea dx, msg_result
mov ah,9
int 21h ;message print
mov ax,bx
mov dx,cx ;restore saved registers values
call func_uint32OUT
mov ah, 4Ch
int 21h ;stop
calc_error:
lea dx, msg_calc_error
mov ah,9
int 21h
mov ah, 4Ch
int 21h ;stop
N_unc:
lea dx, msg_enterN_err
jmp N_reenter
N_decrease:
dec di
jmp next1
M_unc:
lea dx, msg_enterM_err
jmp M_reenter
start endp
;require: ax, bx, cx, dx, si
func_uint16IN proc
mov bx,10 ;prepare bx register
xor ch,ch
label_func_uint16IN_reinput:
lea dx, func_uint16IN_buffer ;set pointer to buffer
mov ah,0Ah ;init string input mode
int 21h ;input string
mov cl, [func_uint16IN_buffer+1]
lea si, func_uint16IN_buffer+2 ;set pointer to first symbol of string to si
xor ax,ax ;zero ax
label_func_uint16IN_loop:
cmp byte ptr [si],'0' ;check symbol code
jb label_func_uint16IN_err
cmp byte ptr [si],'9' ;check symbol code
ja label_func_uint16IN_err
mul bx ;multiply to basis
jc label_func_uint16IN_err
sub byte ptr [si],'0' ;get number from symbol
add al,[si] ;add number to result
adc ah,0
jc label_func_uint16IN_err
inc si
loop label_func_uint16IN_loop ;string to uint16 cycle
ret
label_func_uint16IN_err:
lea dx,func_uint16IN_errmsg
mov ah,9
int 21h
jmp label_func_uint16IN_reinput
func_uint16IN endp
;require: ax, bx, cx, dx, si, di
func_uint32OUT proc
;ax - low word
;dx - high word
xor cx,cx ;zero counter
label_func_uint32OUT_decodeNext:
inc cx ;count digits
call func_div32x16 ;get digit
push bx ;save digit
test ax,ax ;check that digits not finish
jnz label_func_uint32OUT_decodeNext ;if not - repeat
test dx,dx
jnz label_func_uint32OUT_decodeNext ;if not - repeat
mov ah,2 ;prepare DOS output
label_func_uint32OUT_printNext:
pop dx ;get digit
add dx,'0' ;set digit to output
int 21h
loop label_func_uint32OUT_printNext
ret
func_uint32OUT endp
;require: ax, bx, dx, si, di
func_mul32x16 proc
;ax - low word
;dx - high word
;bx - multiplier
mov si,ax ;prepare to high word multiply
mov ax,dx
mul bx
jo label_func_mul32x16_overflow
mov di,ax
mov ax,si ;prepare to low word multiply
mul bx
add dx,di
jc label_func_mul32x16_overflow
ret
label_func_mul32x16_overflow:
stc
ret
func_mul32x16 endp
;require: ax, bx, dx, si, di
func_div32x16 proc
;ax - low word input
;dx - high word input
;func_div32x16_divider - divider
;ax - low word quotient
;dx - high word quotient
;bx - remainder
test dx,dx
jz func_div32x16_simpleDiv
mov di,dx ;LW block - save high word
xor dx,dx
div [func_div32x16_divider] ;divide low word
mov bx,ax ;save quotient low word
mov si,dx ;save remainder low word
mov ax,di ;HW block
xor dx,dx
div [func_div32x16_divider] ;divide high word
mov di,ax ;save quotient high word
xor ax,ax ;HWR block
div [func_div32x16_divider] ;divide high word remainder
add bx,ax
adc di,0
mov ax,dx ;R block
xor dx,dx
add ax,si ;remainder summ
adc dx,0
div [func_div32x16_divider] ;divide remainder summ
add ax,bx
adc di,0
mov bx,dx ;result forming
mov dx,di ;high word to bx
ret
func_div32x16_simpleDiv:
div [func_div32x16_divider]
mov bx,dx
xor dx,dx
ret
func_div32x16 endp
end start