0 / 0 / 0
Регистрация: 03.04.2017
Сообщений: 6
1
TASM

Калькулятор, который выполняет 4 простейших арифметических операций над двумя числами со знаком

03.04.2017, 20:42. Показов 7869. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем доброго времени суток. Такой вопрос: есть калькулятор, который выполняет 4 простейших арифметических операций с двумя числами. Задача заключается в том чтобы его немного модифицировать и упростить согласно тз: написать калькулятор, выполняющий над двумя знаковыми числами размером в слово следующие операции: нахождение максимального, минимального и среднего арифметического значений (все отдельно, можно через процедуры) ну и вывод их на экран соответственно.
Заранее спасибо!
Assembler
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
    .model tiny         ;COM - файл
    .code
    .386                ;используем eax
    org 100h
start:
vvod1:                  ;выбор функции
    xor eax,eax         ;обнуляем регистры
    xor edx,edx         ;
    call clrscr
    mov ah,9            ;Вывод сторки мессаге1 
    mov dx,offset message1      ;   
    int 21h             ;
    mov ah,08h          ;считать символ с клавиатуры        
    int 21h             ;
    cmp al,'+'          ;сравнение с '+' 
    je cloj             ;значит складываем
    cmp al,'-'          
    je vich             ;вычитание
    cmp al,'/'
    je dele             ;деление
    cmp al,'*'
    je rr1              ;используем jmp т.к далеко                
    jmp rr              ;
rr1:    jmp umnoj           ;Умножение
rr: cmp al,'q'          ;выход
    je quit
    cmp al,'Q'
    je quit
    jmp short vvod1         ;если не ввели то повторять ввод  
quit:   
    ret             ;Выход
cloj:                   ;Сложение dx+ax->ax
    call clrscr         ;стереть экран
        
    call aa1            ;ввод а    
    push dx             ;сохраняем dx в стеке
    call bb1            ;ввод b 
    pop dx              ;вытаскиваем dx из стека          
    add ax,dx           ;складываем ax и dx результат в eax
        
    call print
    
    call endstrd
    mov ah,9            ;Вывод сторки мессаге2 
    mov dx,offset message2      ;   
    int 21h
    mov ah,08h
    int 21h             ;
    jmp vvod1
vich:                   ;вычитание
    
    call clrscr         ;стереть экран
    call aa1            ;ввод а    
    push dx
    call bb1            ;ввод b     
    
    pop dx
    sub dx,ax           ;вычитаем из dx ax результат в edx
    mov ax,dx           ;переносим его eax 
    
    call print          ;выводит eax в десятичной системе
    
    call endstrd
    mov ah,9            ;Вывод сторки мессаге2 
    mov dx,offset message2      ;   
    int 21h
    mov ah,08h
    int 21h             ;
    jmp vvod1   
 
dele:                   ;деление (цело численное)
    call clrscr         ;стереть экран
    call aa1            ;ввод а    
    push dx
    call bb1            ;ввод b     
    
    pop dx
    xchg dx,ax
    mov cx,dx           ;сохраняем делитель в cx
    xor dx,dx           ;обнуляем dx там будет остаток
    div cx              ;делим результат в eax
 
    call print
    
    call endstrd
    mov ah,9            ;Вывод сторки мессаге2 
    mov dx,offset message2      ;   
    int 21h
    mov ah,08h
    int 21h             ;
    
 
    jmp vvod1
umnoj:                  ;умножение
    call clrscr         ;стереть экран
    call aa1            ;ввод а    
    push dx
    call bb1            ;ввод b     
    pop dx
    
    mul edx             ;умножаем результат в eax
 
    call print
    
    call endstrd
    mov ah,9            ;Вывод сторки мессаге2 
    mov dx,offset message2      ;   
    int 21h
    mov ah,08h
    int 21h             ;
    jmp vvod1
clrscr:
    xor dx,dx           ;положение курсора dh-строка dl-столбец
    mov ah,02h          ;установить в 0,0
    int 10h             ;
    mov bl,0000111b         ;атрибут символов белый на чёрном
    mov cx,25*80            ;количество символов  
    mov ax,0920h            ;вывод 25*80 пробелов
    int 10h             ;
    ret
    endp
aa1:                    ;ввод а
    mov dx,offset aaaa
    mov ah,9    
    int 21h
    call mover
    mov dx,ax           ;перенесём в dx
    ret
    endp
bb1:                    ;ввод а
    mov dx,offset bbbb
    mov ah,9    
    int 21h
    call mover
    ret
    endp
 
mover:  
    mov dx,offset bufer     ;аресс буфера
    mov ah,0ah          ;считать строку данных в буфер 
    int 21h             ;
    mov dx,offset endstr        ;перенос курсора на строку ниже   
    mov ah,9            ;   
    int 21h             ;   
;перевод из строки в бинарное число
    xor di,di           ;начало буферв
    xor ax,ax           ;текущее значение ax
    mov cl,blength
    xor ch,ch
    xor bx,bx
    mov si,cx           ;длинна буфера  
    mov cl,10           ;множитель
tohex:
    mov bl,byte ptr bconteg[di]
    sub bl,'0'          ;цифра = код символа - код символа '0'
    jb  tata            ;если ко символа < чем код '0'
    cmp bl,9            ;или > чем '9'
    ja  tata            ;начать ввод занаво
    mul cx              ;иначе умножить на 10
    add ax,bx           ;добавить к ax новую цифру   
    inc di              ;увеличить адресс
    cmp di,si           ;если он меньше чем кол. символов + 1     
    jb tohex
    jmp tra
tata:   jmp vvod1           ;Нужно использовать дальний переход
tra:    ret
    endp
 
print:
    
    mov ebx,0ah         ;делитель
    xor cx,cx           ;счётчик
 
divloop:
    xor edx,edx         ;обнуляем edx
    div ebx             ;делим на 10
    add edx,'0'         ;дописываем к остатку деления код нуля
    push edx            ;сохраняем число в стеке
    inc cx              ;увеличиваем счётчик на 1
    test eax,eax            ;если есть что делить то
    jnz divloop         ;продолжаем делить(если не ноль)
restore:
    pop eax             ;читаем записанные числа из стека
    mov edx,eax         ;пишем их в eax 
    mov ah,2            ;функция вывода символа по коду код в al
    int 21h             ;
    dec cx              ;уменьшаем счетчик
    cmp cx,0            ;если он не = нолю
    jne restore         ;то проолжаем вывод
    ret
    endp
 
endstrd:
    mov dx,offset endstr        ;перенос курсора на строку ниже   
    mov ah,9            ;
    int 21h             ;
    ret
    endp
ret
message1 db "PRESS",0dh,0ah
     db "+ for add. a+b.",0dh,0ah
     db "- for sub. a-b",0dh,0ah
     db "/ for div. a/b",0dh,0ah
     db "* for mul. a*b",0dh,0ah
     db "q for quit",0dh,0ah,'$'    
message2 db "Press any key",0dh,0ah,'$'
aaaa     db "a=",'$'
bbbb     db "b=",'$'
endstr   db 0dh,0ah,'$'  
enderes  db ' ',0dh,0ah,'$' 
bufer    db 5               ;max размер ввода чисел
blength  db ?               ;размер буфера после считывания
bconteg:                ;содержимое буфера будет за концом файла
hexstring equ bconteg
end start
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.04.2017, 20:42
Ответы с готовыми решениями:

Написать функцию которая выполняет над нулевыми действительными числами одну из арифметических операций
Написать функцию которая выполняет над нулевыми действительными числами одну из арифметических...

Выполнение арифметических операций над числами
В C # введите программу, которая запрашивает и читает два числа с клавиатуры. После этого программа...

Реализация арифметических операций над вещественными числами
Здравствуйте. Помогите пожалуйста реализовать алгоритмы арифметических операций(+ - * /) над...

Выполнение базовых арифметических операций над числами
Описать функцию Calc (A,B,Op) вещественного типа выполняющую над нулевыми числами А и В одну из...

13
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
03.04.2017, 22:21 2
Для работы со знаковыми - слишком много переделывать. Я бы выбросил этот код и вставил процедуры из закреплённой темы Ввод и вывод чисел в различных системах счисления.
Assembler
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
    .model tiny         ;COM - файл
    .code
    .386                ;используем eax
    org 100h
start:
vvod1:                  ;выбор функции
    xor eax,eax         ;обнуляем регистры
    xor edx,edx         ;
    call clrscr
    mov ah,9            ;Вывод сторки мессаге1
    mov dx,offset message1      ;
    int 21h             ;
    mov ah,08h          ;считать символ с клавиатуры
    int 21h             ;
    cmp al,'m'          ;сравнение с 'm'
    je min              ;значит ищем минимум
    cmp al,'M'
    je MAX              ;максимум
    cmp al,'A'
    je average          ;среднее
rr: cmp al,'q'          ;выход
    je quit
    cmp al,'Q'
    je quit
    jmp short vvod1         ;если не ввели то повторять ввод
quit:
    ret             ;Выход
min:                   ;минимум dx+ax->ax
    call clrscr         ;стереть экран
 
    call aa1            ;ввод а
    push dx             ;сохраняем dx в стеке
    call bb1            ;ввод b
    pop dx              ;вытаскиваем dx из стека
 
    cmp ax,dx
    jle @@m1
    mov ax,dx
@@m1:
    call print
 
    call endstrd
    mov ah,9            ;Вывод сторки мессаге2
    mov dx,offset message2      ;
    int 21h
    mov ah,08h
    int 21h             ;
    jmp vvod1
MAX:                   ;максимум
 
    call clrscr         ;стереть экран
    call aa1            ;ввод а
    push dx
    call bb1            ;ввод b
 
    pop dx
    cmp ax,dx
    jge @@m2
    mov ax,dx           ;переносим его eax
@@m2:
    call print          ;выводит eax в десятичной системе
 
    call endstrd
    mov ah,9            ;Вывод сторки мессаге2
    mov dx,offset message2      ;
    int 21h
    mov ah,08h
    int 21h             ;
    jmp vvod1
 
average:                ;среднее  (цело численное)
    call clrscr         ;стереть экран
    call aa1            ;ввод а
    push dx
    call bb1            ;ввод b
 
    pop dx
 
    add ax,dx           ;складываем ax и dx результат в eax
    sar ax,1            ;делим на 2 при помощи арифметического сдвига
 
    call print
 
    call endstrd
    mov ah,9            ;Вывод сторки мессаге2
    mov dx,offset message2      ;
    int 21h
    mov ah,08h
    int 21h             ;
    jmp vvod1
 
clrscr:
    xor dx,dx           ;положение курсора dh-строка dl-столбец
    mov ah,02h          ;установить в 0,0
    int 10h             ;
    mov bl,0000111b         ;атрибут символов белый на чёрном
    mov cx,25*80            ;количество символов
    mov ax,0920h            ;вывод 25*80 пробелов
    int 10h             ;
    ret
    endp
aa1:                    ;ввод а
    mov dx,offset aaaa
    mov ah,9
    int 21h
    call mover
    mov dx,ax           ;перенесём в dx
    ret
    endp
bb1:                    ;ввод а
    mov dx,offset bbbb
    mov ah,9
    int 21h
    call mover
    ret
    endp
 
mover:
    mov dx,offset bufer     ;аресс буфера
    mov ah,0ah          ;считать строку данных в буфер
    int 21h             ;
    mov dx,offset endstr        ;перенос курсора на строку ниже
    mov ah,9            ;
    int 21h             ;
;перевод из строки в бинарное число
    xor di,di           ;начало буферв
    xor ax,ax           ;текущее значение ax
    mov dx,0            ;число положительное
    mov cl,blength
    xor ch,ch
    xor bx,bx
    mov si,cx           ;длинна буфера
    mov cl,10           ;множитель
tohex:
    mov bl,byte ptr bconteg[di]
    sub bl,'0'          ;цифра = код символа - код символа '0'
    jb  tata            ;если ко символа < чем код '0'
    cmp bl,9            ;или > чем '9'
    ja  tata            ;начать ввод занаво
    mul cx              ;иначе умножить на 10
    add ax,bx           ;добавить к ax новую цифру
    inc di              ;увеличить адресс
    cmp di,si           ;если он меньше чем кол. символов + 1
    jb tohex
    jmp tra
    xor di,di
tata:   jmp vvod1           ;Нужно использовать дальний переход
tra:
    ret
    endp
 
print:
 
    mov ebx,0ah         ;делитель
    xor cx,cx           ;счётчик
 
divloop:
    xor edx,edx         ;обнуляем edx
    div ebx             ;делим на 10
    add edx,'0'         ;дописываем к остатку деления код нуля
    push edx            ;сохраняем число в стеке
    inc cx              ;увеличиваем счётчик на 1
    test eax,eax            ;если есть что делить то
    jnz divloop         ;продолжаем делить(если не ноль)
restore:
    pop eax             ;читаем записанные числа из стека
    mov edx,eax         ;пишем их в eax
    mov ah,2            ;функция вывода символа по коду код в al
    int 21h             ;
    dec cx              ;уменьшаем счетчик
    cmp cx,0            ;если он не = нолю
    jne restore         ;то проолжаем вывод
    ret
    endp
 
endstrd:
    mov dx,offset endstr        ;перенос курсора на строку ниже
    mov ah,9            ;
    int 21h             ;
    ret
    endp
ret
message1 db "PRESS",0dh,0ah
     db "m for min. a+b.",0dh,0ah
     db "M for MAX. a-b",0dh,0ah
     db "A for (a+b)/2",0dh,0ah
     db "q for quit",0dh,0ah,'$'
message2 db "Press any key",0dh,0ah,'$'
aaaa     db "a=",'$'
bbbb     db "b=",'$'
endstr   db 0dh,0ah,'$'
enderes  db ' ',0dh,0ah,'$'
bufer    db 5               ;max размер ввода чисел
blength  db ?               ;размер буфера после считывания
bconteg:                ;содержимое буфера будет за концом файла
hexstring equ bconteg
end start
0
0 / 0 / 0
Регистрация: 03.04.2017
Сообщений: 6
04.04.2017, 07:20  [ТС] 3
Добавлено через 1 час 46 минут
ФедосеевПавел Ну, согласен, этот код достаточно громоздкий. А как можно переделать по-проще? Нашёл по ссылке только вывод знакового числа, он норм, а вот ввод какой-то большой прям. По-идее процедуры можно взять те, которые Вы оставили (для нахождения максимального, минимального и среднего).
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
04.04.2017, 09:44 4
А какая разница в размере - код-то уже есть, заново его делать не требуется.
Тем более, в закреплённой теме два варианта - один чуть проще, другой чуть сложнее. Основная разница в обработке ситуации ввода числа +32768 и в сохранении контекста (регистров).
Можно сократить сохранение и восстановление регистров, заменив несколько команд на pusha и popa, но после слова .code придётся в новой строке добавить директиву .386.
Просто не все студенты знают о такой возможности и чтобы было меньше вопросов новые команды не использовались.

Добавлено через 1 час 57 минут
Так будет со знаковыми числами
Assembler
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
    LOCALS              ;разрешение одинаковых локальных меток (начинающихся с @@)
    .model tiny         ;COM - файл
    .code
    .386                ;используем eax
    org 100h
start:
vvod1:                  ;выбор функции
    call clrscr
    mov ah,9            ;Вывод сторки мессаге1
    mov dx,offset message1      ;
    int 21h             ;
    mov ah,08h          ;считать символ с клавиатуры
    int 21h             ;
    Case1:
        cmp al,'m'      ;сравнение с '+'
        jne Case2
        call EnterAB
        call Min        ;значит возвращаем минимум
        call ShowResult
        jmp vvod1
    Case2:
        cmp al,'M'
        jne Case3
        call EnterAB
        call Max        ;значит возвращаем максимум
        call ShowResult
        jmp vvod1
    Case3:
        cmp al,'a'
        jne Case4
        call EnterAB
        call Average    ;значит возвращаем среднее арифметическое
        call ShowResult
        jmp vvod1
    Case4:
        cmp al,'q'      ;выход
        je quit
        cmp al,'Q'
        je quit
    jmp short vvod1         ;если не ввели то повторять ввод
quit:
    int 20h             ;Выход
;Минимальное число
;на входе:
; ax - первое число
; bx - второе число
;на выходе:
; ax - минимальное из двух чисел
Min     proc
    cmp ax,bx
    jle @@Skip
    mov ax,bx
@@Skip:
        ret
Min     endp
 
;Максимальное число
;на входе:
; ax - первое число
; bx - второе число
;на выходе:
; ax - максимальное из двух чисел
Max     proc
    cmp ax,bx
    jge @@Skip
    mov ax,bx
@@Skip:
        ret
Max     endp
 
;Максимальное число
;на входе:
; ax - первое число
; bx - второе число
;на выходе:
; ax - максимальное из двух чисел
Average proc
    add ax,bx           ;складываем ax и bx результат в ax
    sar ax,1            ;делим на 2 при помощи арифметического сдвига
    ret
Average endp
 
;ввод двух чисел для дальнейших вычислений
;на фходе:
; -
;на выходе:
;ax - число A
;bx - число B
EnterAB proc
    call clrscr
    mov dx,offset aaaa
    mov ah,9
    int 21h
@@ReadA:
    mov ah, 0Ah
    lea dx, bufer
    int 21h
    lea si, bufer+1
    call Str2Num
    jc @@ReadA
    push ax
    call newstr
    mov dx,offset bbbb
    mov ah,9
    int 21h
@@ReadB:
    mov ah, 0Ah
    lea dx, bufer
    int 21h
    lea si, bufer+1
    call Str2Num
    jc @@ReadB
    push ax
    call newstr
    pop bx
    pop ax
    ret
EnterAB endp
 
;вывод строки результата и ожидание нажатия клавиши
;на входе
;ax - знаковое число для вывода в качестве результата
ShowResult      proc
        call Show_AX
        call NewStr
        mov ah,9
        mov dx,offset message2      ;
        int 21h
        mov ah,08h
        int 21h
        mov ah, 06h     ;считываем второй символ при нажатии функциональной клавиши
        mov dl, 0FFh
        int 21h
        ret
ShowResult      endp
 
; преобразования строки в число
; на входе:
; ds:[si] - строка с числом
; на выходе
; ax - число
; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
Str2Num PROC
LOCAL R: word
        pusha
        push    ds
        push    es
        push    si      ;для дальнейшей проверки знака
 
        push    ds
        pop     es
 
        mov     cl, ds:[si]
        xor     ch, ch
 
        inc     si
 
        mov     bx, 10
        xor     ax, ax
 
        ;если в строке первый символ '-'
        ; - перейти к следующему
        ; - уменьшить количество рассматриваемых символов
        cmp     byte ptr [si], '-'
        jne     @@Loop
        inc     si
        dec     cx
@@Loop:
        mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
        mov     [di], ax   ; игнорируем старшее слово
        cmp     dx, 0      ; проверяем, результат на переполнение
        jnz     @@Error
 
        mov     al, [si]   ; Преобразуем следующий символ в число
        cmp     al, '0'
        jb      @@Error
        cmp     al, '9'
        ja      @@Error
        sub     al, '0'
        xor     ah, ah
        add     ax, [di]
        jc      @@Error    ; Если сумма больше 65535
        cmp     ax, 8000h
        ja      @@Error
        inc     si
 
        loop    @@Loop
 
        pop     si         ;проверка на знак
        ;push    si
        inc     si
        cmp     byte ptr [si], '-'
        jne     @@Check    ;если должно быть положительным
        neg     ax         ;если должно быть отрицательным
        jmp     @@StoreRes
@@Check:                   ;дополнительная проверка, когда при вводе положительного числа получили отрицательное
       or       ax, ax     ;
       js       @@Error
@@StoreRes:                ;сохранить результат
        mov     R, ax
        clc
        pop     es
        pop     ds
        popa
        mov     ax, R
        ret
@@Error:
        xor     ax, ax
        mov     R, ax
        stc
        pop     es
        pop     ds
        popa
        mov     ax, R
        ret
Str2Num ENDP
 
; выводит число из регистра AX на экран
; входные данные:
; ax - число для отображения
Show_AX proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    di
 
        mov     cx, 10          ; cx - основание системы счисления
        xor     di, di          ; di - кол. цифр в числе
 
        ; если число в ax отрицательное, то
        ;1) напечатать '-'
        ;2) сделать ax положительным
        or      ax, ax
        jns     @@Conv
        push    ax
        mov     dx, '-'
        mov     ah, 2           ; ah - функция вывода символа на экран
        int     21h
        pop     ax
 
        neg     ax
 
@@Conv:
        xor     dx, dx
        div     cx              ; dl = num mod 10
        add     dl, '0'         ; перевод в символьный формат
        inc     di
        push    dx              ; складываем в стэк
        or      ax, ax
        jnz     @@Conv
        ; выводим из стэка на экран
@@Show:
        pop     dx              ; dl = очередной символ
        mov     ah, 2           ; ah - функция вывода символа на экран
        int     21h
        dec     di              ; повторяем пока di<>0
        jnz     @@Show
 
        pop     di
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Show_AX endp
 
clrscr  proc
    pusha
    xor dx,dx           ;положение курсора dh-строка dl-столбец
    mov ah,02h          ;установить в 0,0
    int 10h             ;
    mov bl,0000111b         ;атрибут символов белый на чёрном
    mov cx,25*80            ;количество символов
    mov ax,0920h            ;вывод 25*80 пробелов
    int 10h             ;
    popa
    ret
clrscr  endp
 
newstr  proc
        pusha
        mov     ah, 09h
        lea     dx, endstr
        int     21h
        popa
        ret
newstr  endp
;------------------------------------------------------------
message1        db "PRESS",0dh,0ah
                db "m for min(a,b).",0dh,0ah
                db "M for max(a,b)",0dh,0ah
                db "a for (a+b)/2",0dh,0ah
                db "q for quit",0dh,0ah,'$'
message2        db "Press any key",0dh,0ah,'$'
aaaa            db "a=",'$'
bbbb            db "b=",'$'
endstr          db 0dh,0ah,'$'
enderes         db ' ',0dh,0ah,'$'
bufer           db 5               ;max размер ввода чисел
blength         db ?               ;размер буфера после считывания
bconteg:                ;содержимое буфера будет за концом файла
 
end start
0
0 / 0 / 0
Регистрация: 03.04.2017
Сообщений: 6
04.04.2017, 22:42  [ТС] 5
ФедосеевПавел, попробовал запустить через dosbox - выдаёт вот это, всё выводится с мусором
Миниатюры
Калькулятор, который выполняет 4 простейших арифметических операций над двумя числами со знаком  
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
04.04.2017, 22:57 6
Не знаю.
Делаю com файл. Запускаю. Вижу. Всё.
Миниатюры
Калькулятор, который выполняет 4 простейших арифметических операций над двумя числами со знаком  
0
Asm/C++/Delphi/Py/PHP/VBA
6528 / 1973 / 228
Регистрация: 14.12.2014
Сообщений: 4,121
Записей в блоге: 12
06.04.2017, 22:57 7
JustBSI,
Код
tasm /m file.asm
tlink /t /x file.obj
Нужна опция /t для tlink!
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
06.04.2017, 23:14 8
Я намекнул ТС, что запускаю com программу. Ожидал какой-нибудь реакции. Но ТС пропал.
0
0 / 0 / 0
Регистрация: 03.04.2017
Сообщений: 6
11.04.2017, 09:47  [ТС] 9
ФедосеевПавел, создал com, всё работает, огромное спасибо! Но есть пару проблем: экран не всегда очищается, возможно, в коде что-то упущена (может вызов процедуры "затирания" экрана; в некоторых местах нет комментариев, не могу понять как это работает и для чего (особенно где ввод двух чисел). Если не трудно - подсобите, пожалуйста
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
12.04.2017, 00:23 10
Я лишь подогнал программу под текущую задачу, а не переделывал её сколько-нибудь кардинально. Поэтому ошибка просто осталась от автора.

Чтобы мне не гадать, приведите тестовый набор действий, где гарантированно будет воспроизведена ошибка.
0
0 / 0 / 0
Регистрация: 03.04.2017
Сообщений: 6
12.04.2017, 09:17  [ТС] 11
ФедосеевПавел, ФедосеевПавел, с затиранием я думаю разберусь, там просто не везде процедура вызывается скорее всего. А вот с комментами сложнее: в процедуре EnterAB вообще не пойму что да как
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
13.04.2017, 00:27 12
;ввод двух чисел для дальнейших вычислений
;на входе:
; -
;на выходе:
;ax - число A
;bx - число B
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
    mov dx,offset aaaa  вывод приглашения
    mov ah,9
    int 21h
@@ReadA:
    mov ah, 0Ah          чтение строки в буфер средствами ОС
    lea dx, bufer
    int 21h
    lea si, bufer+1        преобразование строки в число
    call Str2Num
    jc @@ReadA       если была ошибка преобразования - повторить ввод
    push ax        сохранить значение в стеке
    call newstr           перевод строки
число B вводится аналогично, но в конце сохраняется в регистре bx

Добавлено через 49 секунд
--------------------
Всё. Я не верю, что вы учитесь, а сдать сможете и так.
0
0 / 0 / 0
Регистрация: 03.04.2017
Сообщений: 6
13.04.2017, 05:33  [ТС] 13
ФедосеевПавел, Спасибо! Я учусь, просто чувствую что асм - не моё, не тянет, поэтому не вливаюсь в него с головой (больше интересны языки высокого уровня), а сдавать курсач нужно. Плюс ещё учиться довольно сложно, так как дают много материала и заданий на короткий срок времени.
--------------------------------------
Доброго времени суток. Извиняюсь за беспокойство, хотел ещё кое-что спросить по коду. Когда я вычисляю максимальное или минимальное значение, при отрицательном b у меня не срабатывает очистка экрана, так же и в некоторых других случаях (в том числе и с нахождением среднего арифметического). Иногда, если нажать не ту клавишу, что нужно, программа или зависает или вылетает. Компилирую через obj как парень советовал, так как x64. Помогите, пожалуйста. Спасибо.
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
19.04.2017, 10:48 14
Ну, что вам сказать? Не жмите что попало. Это учебная программа с минимальной обработкой ошибок. Хотите полную защиту - никто не запрещает мечтать и реализовывать.

Не по теме:

За 2 недели многое можно успеть. Я в школе изучил BASIC за 7 дней - это был первое знакомство с компьютерами, далее в течение следующих 2-х недель освоил ещё два диалекта на других компьютерах. Ассемблеры для нескольких процессоров учил в ВУЗе совсем без компьютеров, только по книгам. На x86 ушло около месяца. Учась в ВУЗе ещё и работал и шабашил и по гулькам гулял и пьяным валялся и на моря ездил. Времени хватало.


Что-то исправил, и на этом мой интерес к подобным исправлениям угасает.
Assembler
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
    LOCALS              ;разрешение одинаковых локальных меток (начинающихся с @@)
    .model tiny         ;COM - файл
    .code
    .386                ;используем eax
    org 100h
start:
vvod1:                  ;выбор функции
    call clrscr
    mov ah,9            ;Вывод сторки мессаге1
    mov dx,offset message1      ;
    int 21h             ;
    mov ah,08h          ;считать символ с клавиатуры
    int 21h             ;
    Case1:
        cmp al,'m'      ;сравнение с '+'
        jne Case2
        call EnterAB
        call Min        ;значит возвращаем минимум
        call ShowResult
        jmp vvod1
    Case2:
        cmp al,'M'
        jne Case3
        call EnterAB
        call Max        ;значит возвращаем максимум
        call ShowResult
        jmp vvod1
    Case3:
        cmp al,'a'
        jne Case4
        call EnterAB
        call Average    ;значит возвращаем среднее арифметическое
        call ShowResult
        jmp vvod1
    Case4:
        cmp al,'q'      ;выход
        je quit
        cmp al,'Q'
        je quit
    jmp short vvod1         ;если не ввели то повторять ввод
quit:
    int 20h             ;Выход
;Минимальное число
;на входе:
; ax - первое число
; bx - второе число
;на выходе:
; ax - минимальное из двух чисел
Min     proc
    cmp ax,bx
    jle @@Skip
    mov ax,bx
@@Skip:
        ret
Min     endp
 
;Максимальное число
;на входе:
; ax - первое число
; bx - второе число
;на выходе:
; ax - максимальное из двух чисел
Max     proc
    cmp ax,bx
    jge @@Skip
    mov ax,bx
@@Skip:
        ret
Max     endp
 
;Максимальное число
;на входе:
; ax - первое число
; bx - второе число
;на выходе:
; ax - максимальное из двух чисел
Average proc
    add ax,bx           ;складываем ax и bx результат в ax
    sar ax,1            ;делим на 2 при помощи арифметического сдвига
    ret
Average endp
 
;ввод двух чисел для дальнейших вычислений
;на входе:
; -
;на выходе:
;ax - число A
;bx - число B
EnterAB proc
    call clrscr
@@ReadA:
    mov dx,offset aaaa
    mov ah,9
    int 21h
    mov ah, 0Ah
    lea dx, bufer
    int 21h
    lea si, bufer+1
    call Str2Num
    jc @@ReadA
    push ax
    call newstr
@@ReadB:
    mov dx,offset bbbb
    mov ah,9
    int 21h
    mov ah, 0Ah
    lea dx, bufer
    int 21h
    lea si, bufer+1
    call Str2Num
    jc @@ReadB
    push ax
    call newstr
    pop bx
    pop ax
    ret
EnterAB endp
 
;вывод строки результата и ожидание нажатия клавиши
;на входе
;ax - знаковое число для вывода в качестве результата
ShowResult      proc
        call Show_AX
        call NewStr
        mov ah,9
        mov dx,offset message2      ;
        int 21h
        mov ah,08h
        int 21h
        mov ah, 06h     ;считываем второй символ при нажатии функциональной клавиши
        mov dl, 0FFh
        int 21h
        ret
ShowResult      endp
 
; преобразования строки в число
; на входе:
; ds:[si] - строка с числом
; на выходе
; ax - число
; CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
Str2Num PROC
LOCAL R: word
        pusha
        push    ds
        push    es
 
        push    ds
        pop     es
 
        mov     cl, ds:[si]
        xor     ch, ch
        jcxz    @@Error
        push    si      ;для дальнейшей проверки знака
        inc     si
 
        mov     bx, 10
        xor     ax, ax
 
        ;если в строке первый символ '-'
        ; - перейти к следующему
        ; - уменьшить количество рассматриваемых символов
        cmp     byte ptr [si], '-'
        jne     @@Loop
        inc     si
        dec     cx
@@Loop:
        mul     bx         ; умножаем ax на 10 ( dx:ax=ax*bx )
        mov     [di], ax   ; игнорируем старшее слово
        cmp     dx, 0      ; проверяем, результат на переполнение
        jnz     @@ErrorWithPopSI
 
        mov     al, [si]   ; Преобразуем следующий символ в число
        cmp     al, '0'
        jb      @@ErrorWithPopSI
        cmp     al, '9'
        ja      @@ErrorWithPopSI
        sub     al, '0'
        xor     ah, ah
        add     ax, [di]
        jc      @@ErrorWithPopSI    ; Если сумма больше 65535
        cmp     ax, 8000h
        ja      @@ErrorWithPopSI
        inc     si
 
        loop    @@Loop
 
        pop     si         ;проверка на знак
        inc     si
        cmp     byte ptr [si], '-'
        jne     @@Check    ;если должно быть положительным
        neg     ax         ;если должно быть отрицательным
        jmp     @@StoreRes
@@Check:                   ;дополнительная проверка, когда при вводе положительного числа получили отрицательное
        or       ax, ax    ;
        js       @@Error
@@StoreRes:                ;сохранить результат
        mov     R, ax
        clc
        pop     es
        pop     ds
        popa
        mov     ax, R
        ret
@@ErrorWithPopSI:
        pop     si
@@Error:
        xor     ax, ax
        mov     R, ax
        stc
        pop     es
        pop     ds
        popa
        mov     ax, R
        ret
Str2Num ENDP
 
; выводит число из регистра AX на экран
; входные данные:
; ax - число для отображения
Show_AX proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    di
 
        mov     cx, 10          ; cx - основание системы счисления
        xor     di, di          ; di - кол. цифр в числе
 
        ; если число в ax отрицательное, то
        ;1) напечатать '-'
        ;2) сделать ax положительным
        or      ax, ax
        jns     @@Conv
        push    ax
        mov     dx, '-'
        mov     ah, 2           ; ah - функция вывода символа на экран
        int     21h
        pop     ax
 
        neg     ax
 
@@Conv:
        xor     dx, dx
        div     cx              ; dl = num mod 10
        add     dl, '0'         ; перевод в символьный формат
        inc     di
        push    dx              ; складываем в стэк
        or      ax, ax
        jnz     @@Conv
        ; выводим из стека на экран
@@Show:
        pop     dx              ; dl = очередной символ
        mov     ah, 2           ; ah - функция вывода символа на экран
        int     21h
        dec     di              ; повторяем пока di<>0
        jnz     @@Show
 
        pop     di
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
Show_AX endp
 
clrscr  proc
        pusha
        mov     ax,     0700h   ;функция SCROLL DOWN
        ;mov    al,     10      ;число пустых строк, вдвигаемых сверху (0=очистить все окно)
        mov     bh,     07h     ;атрибут для заполнения
        mov     cx,     0000h   ;верхний левый угол окна (считая от 0)
        mov     dx,     24*256+79 ;нижний правый угол окна (считая от 0)
        int     10h
        mov     ah,     0Fh     ;читать текущий видеорежим
        int     10h
        mov     ah,     02h     ;установить курсор в левый верхний угол
        mov     dx,     0000h   ;левый верхний угол
        int     10h
        popa
        ret
clrscr  endp
 
newstr  proc
        pusha
        mov     ah, 09h
        lea     dx, endstr
        int     21h
        popa
        ret
newstr  endp
;------------------------------------------------------------
message1        db "PRESS",0dh,0ah
                db "m for min(a,b).",0dh,0ah
                db "M for max(a,b)",0dh,0ah
                db "a for (a+b)/2",0dh,0ah
                db "q for quit",0dh,0ah,'$'
message2        db "Press any key",0dh,0ah,'$'
aaaa            db "a=",'$'
bbbb            db "b=",'$'
endstr          db 0dh,0ah,'$'
enderes         db ' ',0dh,0ah,'$'
bufer           db 5               ;max размер ввода чисел
blength         db ?               ;размер буфера после считывания
bconteg:                ;содержимое буфера будет за концом файла
 
end start
0
19.04.2017, 10:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.04.2017, 10:48
Помогаю со студенческими работами здесь

Определить процедуры вычисления арифметических операций над комплексными числами
Помогите написать программу на Python. Задание : Даны действительные числа u1,u2,v1,v2,w1,w2....

Определить процедуры работы арифметических операций над комплексными числами
Дано действительные числа u1,u2, v1,v2, w1,w2. Получить 2*u + (3*u*w/2+w-v) -7, где u,v,w -...

Функции для выполнения арифметических операций над комплексными числами
№1 Заданы два комплексных числа (a+ib) и (c+id) и тип операции(+, -, *, /). Создать функции для...

Определить функции выполнения арифметических операций над комплексными числами
Здравствуйте. Помогите пожалуйста. Даны действительные числа...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru