-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCalc.asm
169 lines (154 loc) · 3.43 KB
/
Calc.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
dosseg
.model small
.data
greating_msg db "Welcome in 8086-Calculator type simple equations to solve",10," Examples : 1+1 or 5*8",10,"$"
error_msg db 10,"Exit due error$"
division_reminder_msg db " and remainder=$"
input db 3 DUP('0')
.code
; printing greating_msg
mov dx,@data ;move offsets to data segment
mov ds,dx
mov ah,9
mov dx,offset greating_msg
int '!' ; '!' = 21h
mov bx,0
take_input: ; loop to take input and print dl for each letter
mov ah,8 ; to input 1 character
int '!'
mov cl,al
cmp bx,1 ; if it's the second character then it's opreation
je check_cl_opreation
call check_cl_number
cmp al,1
je assign
jmp print_error_and_quit
check_cl_opreation: ; to check if the input operation is a supported one
cmp cl,'+'
je assign
cmp cl,'-'
je assign
cmp cl,'*'
je assign
cmp cl,'/'
je assign
jmp print_error_and_quit
assign:
call print_cl
mov input[bx],cl
inc bx
cmp bx,3
jne take_input
calculate_input:
mov cl,input[0] ; First number
mov bl,input[1] ; the mark between the numbers
mov ch,input[2] ; Second number
cmp bl,'+'
je adding
cmp bl,'-'
je subtracting
cmp bl,'*'
je multiplying
cmp bl,'/'
je dividing
print_error_and_quit:
mov ah,9
mov dx,offset error_msg
int '!' ; '!' = 21h
quit: ; Quit the program
mov ah,'L' ; 'L' = 4Ch
int '!'
adding:
call print_equal_sign
sub ch,'0'
add cl,ch
mov ch,'0' ; ch will be used as 10's number
jmp check_and_print_cx
subtracting:
call print_equal_sign
sub ch,'0'
sub cl,ch
call check_cl_number
cmp al,1
je print_sub
mov bh,cl
mov cl,'-'
call print_cl
mov cl,':' ; ':' = '9'+1
sub bh,'0' ; make bh contains exact number
add bh,10 ; add 10 to get number in positive in next instruction
sub cl,bh ; remove bh from cl to get positive number in cl
print_sub:
call print_cl
jmp quit
multiplying:
call print_equal_sign
sub ch,'0'
sub cl,'0'
mov al,ch
mul cl
mov cl,al
mov ch,ah
add cl,'0'
add ch,'0'
call check_and_print_cx
check_and_print_cx:
call check_cl_number
cmp al,1
je print_cx
inc ch
sub cl,10
jmp check_and_print_cx
print_cx:
cmp ch,'0'
je print_units
mov bh,cl ; using bh as temp
mov cl,ch
call print_cl
mov cl,bh
print_units:
call print_cl
jmp quit
dividing:
call print_equal_sign
sub cl,'0' ; to use the real value of cl not '0'+value
sub ch,'0' ; to use the real value of ch not '0'+value
mov ah,0 ; clear ah to use ax in division
mov al,cl
mov bl,ch
div bl
mov ch,ah
mov cl,al
add cl,'0'
call print_cl
mov ah,9
cmp ch,0
je quit_division
mov dx,offset division_reminder_msg
int '!' ; '!' = 21h
mov cl,ch
add cl,'0'
call print_cl
quit_division:
jmp quit
print_equal_sign:
mov ah,2
mov dl,'='
int '!'
ret
print_cl:
mov ah,2
mov dl,cl
int '!'
ret
check_cl_number: ; check if the CL is a number if so return 1 in AL else return 0 in AL
cmp cl,'0'
jb not_number
cmp cl,'9'
ja not_number
mov al,1
ret
not_number:
mov al,0
ret
end