-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadd.asm
242 lines (196 loc) · 3.82 KB
/
add.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
.model small
.386
theStack SEGMENT PARA STACK 'stack' USE16
db 100h DUP(?)
theStack ENDS
data SEGMENT USE16
result db 11 DUP(?)
prompt1 db "Enter the first number (-32768..32767): ", '$'
prompt2 db "Enter the second number (-32768..32767): ", '$'
maxlen1 db 7
num1_len db 0
num1 db 7 DUP(?)
maxlen2 db 7
num2_len db 0
num2 db 7 DUP(?)
plus_sign db " + ", '$'
equal_sign db " = ", '$'
data ENDS
code SEGMENT USE16
ASSUME CS:code, DS:data, ES:data, SS:theStack
print_newline:
mov dl, 10
mov ah, 02h
int 21h
ret
; Convert 32-bit integer to string
; Args:
; eax - 32-bit integer
; edi - address of the buffer
; Return:
; eax - length of the string
; edi - address of the string
int_to_str:
push bp
mov bp, sp
push ebx
push ecx
push edx
push edi
mov ebx, 10 ; Store divider in ebx
xor ecx, ecx ; Initialize counter
cmp eax, 0
jge .push_digits
; Handle negative number
mov edx, eax ; Save eax
mov eax, '-'
stosb
mov eax, edx ; Restore eax
neg eax
.push_digits:
xor edx, edx
div ebx ; Divide by 10
add edx, 30h ; Convert digit to ASCII char
push edx
inc ecx
test eax, eax
jnz .push_digits
.pop_digits:
pop eax
stosb ; Write char to the buffer
dec ecx
test ecx, ecx
jne .pop_digits
; Append NULL
mov eax, '$'
stosb
mov eax, edi
pop edi
pop edx
pop ecx
pop ebx
mov sp, bp
pop bp
; Return number of bytes
sub eax, edi
ret
; Convert string to 32-bit integer
; Args:
; al - address of the string
; Return:
; eax - integer
str_to_int:
push bp
mov bp, sp
push ebx
push ecx
push edi
push esi
mov ebx, 10 ; Store multipler in ebx
mov ecx, eax ; Save string address in ecx
and ecx, 00ffh ; Cleanup
xor esi, esi ; Initialize negative number flag
xor eax, eax
; Handle negative number
mov edi, [ecx]
and edi, 00ffh ; Cleanup
cmp edi, '-'
jne .loop
inc ecx
mov esi, 1
.loop:
mov edi, [ecx]
and edi, 00ffh ; Cleanup
; If we encountered NULL, exit the loop
cmp edi, '$'
je .end_loop
mul ebx
sub edi, 30h ; Convert ASCII to digit
add eax, edi
inc ecx
jmp .loop
.end_loop:
; Negate number if the negative number flag is set
test esi, esi
je .finish
neg eax
.finish:
pop esi
pop edi
pop ecx
pop ebx
mov sp, bp
pop bp
ret
start:
; Initialize data segment
mov ax, SEG data
mov ds, ax
mov es, ax
; Print the first prompt
mov ah, 09h
mov dx, OFFSET prompt1
int 21h
; Read the first number
mov ah, 0ah
mov dx, OFFSET maxlen1
int 21h
call print_newline
; Append NULL to the first number
mov al, num1_len
cbw ; Extend al to ax
mov si, ax
mov num1+si, '$'
; Print the second prompt
mov ah, 09h
mov dx, OFFSET prompt2
int 21h
; Read the second number
mov ah, 0ah
mov dx, OFFSET maxlen2
int 21h
call print_newline
; Append NULL to the second number
mov al, num2_len
cbw ; Extend al to ax
mov si, ax
mov num2+si, '$'
; Convert the first number to int
mov al, OFFSET num1
call str_to_int
mov ebx, eax
; Convert the second number to int
mov al, OFFSET num2
call str_to_int
add eax, ebx
; Convert their sum to string
mov edi, DWORD PTR result
call int_to_str
mov ebx, eax
; Print the first number
mov ah, 09h
mov dx, OFFSET num1
int 21h
; Print plus sign
mov ah, 09h
mov dx, OFFSET plus_sign
int 21h
; Print the second number
mov ah, 09h
mov dx, OFFSET num2
int 21h
; Print equal sign
mov ah, 09h
mov dx, OFFSET equal_sign
int 21h
; Print the result
mov ah, 09h
mov dx, OFFSET result
int 21h
call print_newline
; Exit with status 0
mov ah, 4ch
mov al, 00h
int 21h
code ENDS
end start