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
| model SMALL
stack 100h
dataseg
;;;;;;;;;;;;;;;;; приглашение на ввод первого числа ;;;;;;;;;;;;;;
Ask1 db 0Ah,0Dh,'Vvedite 1 umenshaemoe:$'
;;;;;;;;;;;;;;;;; приглашение на ввод второго числа ;;;;;;;;;;;;;;
Ask2 db 0Ah,0Dh,'Vvedite 2 vichitaemoe:$'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Buf1 db 11
Len1 db ? ; длина 1 строки
Opnd1 db 12 dup( ? ) ; буфер 1 числа
Buf2 db 11
Len2 db ? ; длина 2 строки
Opnd2 db 12 dup( ? ) ; буфер 2 числа
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;; приглашение на вывод результата ;;;;;;;;;;;;;;;;
ResT db 0Ah,0Dh,'Raznost '
Res db 12 dup(' '),'$' ; буфер результата
;;;;;;;;;;;;;;;;; запрос о продолжении работы ;;;;;;;;;;;;;;;;;;;;
AskCont db 0Ah,0Dh
db 'Shut down - Esc, Continue - any key'
db '$'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
codeseg
startupcode
push DS
pop ES ; ES <- DS
BEGIN:
;;;;;;;; ввод первого числа ;;;;;;;;;;;;;;;;;;;;;
B1: lea DX, Ask1 ; в DX занести адрес строки
mov AH, 09h ; в АН занести номер функции (вывод)
int 21h ; вызов прерывания
lea DX, Buf1 ; в DX занести адрес строки
mov AH, 0Ah ; в АН занести номер функции (ввод)
int 21h ; вызов прерывания
cmp Len1, 0 ; сравниваем длину строки с нулем
je B1 ; если равен нулю, то вводим заново
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; проверка 0-9 и очистка старшей тетрады ;;;;;;
lea BX, Opnd1
xor CX, CX ; обнулить регистр CX
mov CL, Len1 ; в СL занести длину строки
xor SI, SI ; обнулить регистр SI
T1: ;;;;; начало цикла ;;;;;;;;;
mov AL, [BX][SI]
cmp AL, '0' ; сравнить с кодом нуля
jb B1 ; если ниже, ошибка
cmp AL, '9' ; сравнить с кодом девятки
ja B1 ; если выше, ошибка
and AL, 0Fh ; обнулить старшую тетраду (АL & 0000 1111)
mov [BX][SI], AL; занести результат в массив
inc SI ; перейти к следующему элементу
loop T1 ; проверка на конец цикла и переход на метку
;;;;; конец цикла ;;;;;;;;;;
;;;;;;;;;;;;; прижать к правому краю ;;;;;;;;;;;
mov CL, Len1 ; в CL занести длину строки
cmp CL, 10 ; сравнить СL с 10
je E1 ; если равно, то перейти на метку
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov DI, 9 ; в DI занести смещение (адрес конца строки)
mov SI, CX ; в SI занести смещение (адрес первого разряда + 1)
dec SI ; уменьшить SI на единицу
P1: ;;;; начало цикла ;;;;;;;
mov AL, [BX][SI]; в АL занести элемент массива
mov [BX][DI], AL; поместить AL в правую часть массива
dec DI ; уменьшить DI на единицу
dec SI ; уменьшить SI на единицу
loop P1 ; проверить на конец цикла и перейти по метке
;;;; конец цикла ;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;; обнулить лишнее ;;;;;;;;;;;;;;;;;;;;;;;
xor DI, DI ; обнулить регистр DI
mov CL, 10 ; занести в регистр СL значение 10
sub CL, Len1 ; отнять от CL длину строки
N1: ;;;;; начало цикла ;;;;;;
mov byte ptr [BX][DI], 0; заменить на нуль
inc DI ; увеличить DI на единицу
loop N1 ; проверить на конец цикла и перейти по метке
;;;;; конец цикла ;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
E1:
;;;;;;;;;;; ввод второго числа ;;;;;;;;;;;;;;;;;
B2: lea DX, Ask2 ; в DX занести адрес строки
mov AH, 09h ; в АН занести номер функции (вывод)
int 21h ; вызов прерывания
lea DX, Buf2 ; в DX занести адрес строки
mov AH, 0Ah ; в АН занести номер функции (ввод)
int 21h ; вызов прерывания
cmp Len2, 0 ; сравниваем длину строки с нулем
je B2 ; если равен нулю, то вводим заново
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; проверка 0-9 и очистка старшей тетерады ;
lea BX, Opnd2
xor CX, CX ; обнулить регистр CX
mov CL, Len2 ; в СL занести длину строки
xor SI, SI ; обнулить регистр SI
T2: mov AL, [BX][SI]
cmp AL, '0' ; сравнить с кодом нуля
jb B2 ; если ниже, ошибка
cmp AL, '9' ; сравнить с кодом девятки
ja B2 ; если выше, ошибка
and AL, 0Fh ; обнулить старшую тетраду (АL & 0000 1111)
mov [BX][SI], AL; занести результат в массив
inc SI ; перейти к следующему элементу
loop T2 ; проверка на конец цикла и переход на метку
;;;;; конец цикла ;;;;;;;;;;
;;;;;;;;;;;;; прижать к правому краю ;;;;;;;;;;;
mov CL, Len2 ; в CL занести длину строки
cmp CL, 10 ; сравнить СL с 10
je E2 ; если равно, то перейти на метку
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov DI, 9 ; в DI занести смещение (адрес конца строки)
mov SI, CX ; в SI занести смещение (адрес первого разряда + 1)
dec SI ; уменьшить SI на единицу
P2: ;;;; начало цикла ;;;;;;;
mov AL, [BX][SI]; в АL занести элемент массива
mov [BX][DI], AL; поместить AL в правую часть массива
dec DI ; уменьшить DI на единицу
dec SI ; уменьшить SI на единицу
loop P2 ; проверить на конец цикла и перейти по метке
;;;; конец цикла ;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;; обнулить лишнее ;;;;;;;;;;;;;;;;;;;;;;;
xor DI, DI ; обнулить регистр DI
mov CL, 10 ; занести в регистр СL значение 10
sub CL, Len2 ; отнять от CL длину строки
N2: ;;;;; начало цикла ;;;;;;
mov byte ptr [BX][DI], 0; заменить на нуль
inc DI ; увеличить DI на единицу
loop N2 ; проверить на конец цикла и перейти по метке
;;;;; конец цикла ;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
E2:;;;;; Вычитание чисел ;;;;;;;;;;;;;;;;;;;;;;;
mov CX, 10 ; установить счетчик
clc
lea SI, Opnd1+9 ; в SI занести адрес массива
lea DI, Opnd2+9 ; в DI занести адрес массива
lea BX, Res+10 ; в ВХ занести адрес массива
A1: ;;;;;; начало цикла ;;;;;
mov AL, [SI] ; в АL занести текущий элемент
sbb AL, [DI] ;вычитание
aas ; произвести десятичную коррекцию вычитания
mov [BX], AL
dec SI ; уменьшить SI на единицу
dec DI ; уменьшить DI на единицу
dec BX ; уменьшить BX на единицу
loop A1 ; проверка на конец цикла и переход по метке
mov AL, 0
adc AL, 0
mov [BX], AL
;;;;;;;;Преобразование результата в ASCII;;;;;;;;;
mov CX, 11
A2: or byte ptr [BX], 30h
inc BX ; увеличить BX на единицу
loop A2 ; проверка на конец цикла и переход по метке
;Вывод результата
lea DX, ResT ; в DX занести адрес строки
mov AH, 09h ; в АН занести номер функции (вывод)
int 21h ; вызвать прерывание
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; запрос на продолжение работы ;;;;;;;;;;;;;
lea DX, AskCont ; в DX занести адрес строки
mov AH, 09h ; в АH занести номер функции (вывод)
int 21h ; вызвать прерывание
mov AH, 08h ; в АН занести номер функции (ввод)
int 21h ; вызвать прерывание
cmp AL, 27 ; проверить на нажатие Esc
je QUIT ; была нажата Esc, завершить программу
jmp BEGIN ; переход в начало программы
;Конец работы
QUIT: exitcode 0 ; вернуть в ОС код 0
end ; конец программы |