Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
elia_ches
0 / 0 / 1
Регистрация: 27.11.2017
Сообщений: 5
1

Ввести с клавиатуры два операнда, найти их сумму и вывести на экран (результат не должен превышать 999)

07.11.2019, 22:09. Просмотров 1744. Ответов 13

Здравствуйте, у меня случилась такая затара. Нужно написать код, где вводится с клавиатуры два числа (либо однозначные, либо двузначные, либо трёхзначные), затем ищется их сумма и выводится результат на экран, который не должен превышать 999. Никак не получается сделать, помогите, пожалуйста
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.11.2019, 22:09
Ответы с готовыми решениями:

13

ФедосеевПавел
Модератор
4732 / 2633 / 1051
Регистрация: 01.02.2015
Сообщений: 8,616
Записей в блоге: 1
07.11.2019, 22:17 2
А в чём остановка?
0
elia_ches
0 / 0 / 1
Регистрация: 27.11.2017
Сообщений: 5
07.11.2019, 22:21  [ТС] 3
У меня получилось решение, когда вводится только 2-х значные числа, но с 3-х значными и 1 значными не могу понять. Я новичок в этом деле, обыскала темы, нашла только варианты решения либо суммы двухзначных, либо однозначных. Но чтобы всё вместе - не нашла
0
ФедосеевПавел
Модератор
4732 / 2633 / 1051
Регистрация: 01.02.2015
Сообщений: 8,616
Записей в блоге: 1
07.11.2019, 22:58 4
Та ладно! А закреплённую тему уже почитали?
Ввод и вывод чисел в различных системах счисления

Да и в чём сложность?
Вот пусть у вас есть строка S длиной strlenS. Преобразуем её в число.
1. примем, что результат пока равен 0 r=0
2. берём очередной символ строки S[i].
3. преобразуем его в цифру. Это просто, т.к. в таблице кодов символов цифры идут по порядку и символ "ноль" имеет самый меньший код, а символ цифры "девять" - самый большой. Т.е. в ассемблере это просто - вычитаем из символа строки S[i] код символа "ноль" d=S[i]-'0'. Теперь в нашем регистре - число, равное цифре в символе строки.
3. Раз символ S[i] есть, значит нужно "приписать" цифру из этого символа правее числа r. Т.е. умножим r на 10 и сложим результат с нашей новой цифрой r=r*10+d
4. проверяем - строка закончилась? если ещё нет - переходим к п.2

А преобразование числа в строку чуть отличается, т.к. остатки от деления на 10 получаются в обратном порядке - сначала младшие цифры, а потом старшие. Чтобы изменить их порядок - по мере получения остатков их сохраняют в стеке, а потом для вывода на экран - извлекают.

Вот и всё.
0
07.11.2019, 22:58
elia_ches
0 / 0 / 1
Регистрация: 27.11.2017
Сообщений: 5
07.11.2019, 23:49  [ТС] 5
хорошо, это вроде стало понятно. а если у нас пара чисел на ввод, а не одно? как запомнить первое введеное число, чтобы второе число не перезаписало значение первого? как-то возможно сделать так, чтобы были, так называемые, переменные, где хранятся два этих числа, чтобы потом над ними выполнять операции?
0
Mikl___
Автор FAQ
14333 / 6683 / 700
Регистрация: 11.11.2010
Сообщений: 12,009
08.11.2019, 04:28 6
Цитата Сообщение от elia_ches Посмотреть сообщение
а если у нас пара чисел на ввод, а не одно? как запомнить первое введеное число, чтобы второе число не перезаписало значение первого? как-то возможно сделать так, чтобы были, так называемые, переменные, где хранятся два этих числа, чтобы потом над ними выполнять операции?
elia_ches,
а как же сообщение
Цитата Сообщение от elia_ches Посмотреть сообщение
У меня получилось решение, когда вводится только 2-х значные числа, но с 3-х значными и 1 значными не могу понять
то есть с двухзначными числами вопросов о том "как вводить два числа" не возникало, а теперь внезапно возникли? где-то, кто-то нагло обманывает...
0
ФедосеевПавел
Модератор
4732 / 2633 / 1051
Регистрация: 01.02.2015
Сообщений: 8,616
Записей в блоге: 1
08.11.2019, 11:53 7
elia_ches, объявляете переменные в сегменте данных, после ввода первой строки и преобразования её в число - сохраняете значение в переменной. Потом вводите, обрабатываете вторую строку и во второй переменной сохраняете второе число.

Я очень сожалею, что в школах не ограничивают обучение только чтением, а зачем-то ещё учат письму. Это приводит к тому, что большинство, не умеют читать - только печатать.
Вот, например, вы - elia_ches. По правде, для решения данной задачки достаточно знать некоторые азы ассемблера и внимательно прочитать ВСЁ что я набирал для вас лично в сообщении #4.
Пока воздержусь от повторного указания на почти готовое решение, надеюсь, что вы осилите сообщение #4 и всё сможете увидеть.

Добавлено через 14 минут
elia_ches, предлагаю поступить следующим образом - создавать программу постепенно наращивая функционал:
1. программа, которая выводит содержимое переменной Result на экран
2. программа складывает две переменные A и B, сумму помещает в переменную Result, выводит содержимое Result на экран
3. программа вводит переменную A, складывает её значение со значением переменной B, сумму помещает в переменную Result, выводит содержимое Result на экран
4. программа вводит две переменные A и B, складывает две переменные A и B, сумму помещает в переменную Result, выводит содержимое Result на экран

Я бы так решал.

Попробуйте и вы последовательно создать такие 4 программы.
1
elia_ches
0 / 0 / 1
Регистрация: 27.11.2017
Сообщений: 5
08.11.2019, 14:48  [ТС] 8
спасибо за помощь, но хочется всё-таки высказаться. Прежде чем осуждать человека, стоит подумать, что он может быть новичком, который только начал изучение и ему многое из того, что легко для любителя/профессионала - НЕ понятно в этом языке. Я смогла найти пример ввода двузначных чисел, поэтому мне это было понятно, но про ввод других - не совсем. В любом случае я продолжу обучение.
0
ФедосеевПавел
Модератор
4732 / 2633 / 1051
Регистрация: 01.02.2015
Сообщений: 8,616
Записей в блоге: 1
08.11.2019, 16:06 9
Хорошо.

Попробуйте создать 4 программы последовательно наращивая функционал. И ещё раз перечитайте сообщение #4.

Добавлено через 48 минут
1. программа, которая выводит содержимое переменной Result на экран
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
.model tiny
 
.code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        Result  dw      987
start:
        ;программа
        mov     ax,     [Result]
        ;выводим содержимое регистра ax на экран
        mov     bx,     10              ;делитель (основание системы счисления)
        mov     cx,     0               ;количество выводимых цифр
        @@div:
                xor     dx,     dx      ;делим (dx:ax) на bx
                div     bx
                add     dl,     '0'     ;преобразуем остаток деления в символ цифры
                push    dx              ;и сохраняем его в стеке
                inc     cx              ;увеличиваем счётчик цифр
                test    ax,     ax      ;в числе ещё есть цифры?
        jnz     @@div                   ;да - повторить цикл выделения цифры
        @@show:
                mov     ah,     02h     ;функция ah=02h int 21h - вывести символ из dl на экран
                pop     dx              ;извлекаем из стека очередную цифру
                int     21h             ;и выводим её на экран
        loop    @@show                  ;и так поступаем столько раз, сколько нашли цифр в числе (cx)
 
        ;завершение программы
        int     20h
main    endp
 
end     main


Добавлено через 1 минуту
Следующую программу - попробуйте сделать самостоятельно

Добавлено через 24 минуты
2. программа складывает две переменные A и B, сумму помещает в переменную Result, выводит содержимое Result на экран
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
.model tiny
 
.code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        A       dw      123
        B       dw      456
        Result  dw      987
start:
        ;программа
        ;сложение переменных
        mov     ax,     [A]
        add     ax,     [B]
        mov     [Result],       ax
        ;вывод значения Result на экран
        mov     ax,     [Result]
        ;выводим содержимое регистра ax на экран
        mov     bx,     10              ;делитель (основание системы счисления)
        mov     cx,     0               ;количество выводимых цифр
        @@div:
                xor     dx,     dx      ;делим (dx:ax) на bx
                div     bx
                add     dl,     '0'     ;преобразуем остаток деления в символ цифры
                push    dx              ;и сохраняем его в стеке
                inc     cx              ;увеличиваем счётчик цифр
                test    ax,     ax      ;в числе ещё есть цифры?
        jnz     @@div                   ;да - повторить цикл выделения цифры
        @@show:
                mov     ah,     02h     ;функция ah=02h int 21h - вывести символ из dl на экран
                pop     dx              ;извлекаем из стека очередную цифру
                int     21h             ;и выводим её на экран
        loop    @@show                  ;и так поступаем столько раз, сколько нашли цифр в числе (cx)
 
        ;завершение программы
        int     20h
main    endp
 
end     main
0
Constantin Cat
9904 / 1441 / 414
Регистрация: 28.02.2015
Сообщений: 2,944
Завершенные тесты: 1
08.11.2019, 16:10 10
Цитата Сообщение от elia_ches Посмотреть сообщение
Я смогла найти пример ввода двузначных чисел, поэтому мне это было понятно, но про ввод других - не совсем
Мы Вас не осуждаем.
Существенно отличается ввод однозначных чисел и ввод двух и более цифр в многозначных числах. Если бы Вы выложили найденный Вами код, Вам бы подсказали, что исправить, чтобы вводить 3-х значные числа.
0
ФедосеевПавел
Модератор
4732 / 2633 / 1051
Регистрация: 01.02.2015
Сообщений: 8,616
Записей в блоге: 1
08.11.2019, 17:20 11
3. программа вводит переменную A, складывает её значение со значением переменной B, сумму помещает в переменную Result, выводит содержимое Result на экран
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
.model tiny
 
.code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        A               dw      123
        B               dw      456
        Result          dw      987
        ;переменные для ввода и вывода
        KeyBuf          db      7, 0, 7 dup(0)      ;max,len,string,CR(0dh)
        CR_LF           db      0Dh, 0Ah, '$'
        PromptA         db      'Введите число A (0..999): ', '$'
        ErrorGetUInt16  db      'Ошибка ввода числа', 0Dh, 0Ah, '$'
start:
        ;программа
        ; ввод числа A с клавиатуры (строки)
        lea     si,     [PromptA]
        call    GetUInt16
        mov     [A],    ax
        ;сложение переменных
        mov     ax,     [A]
        add     ax,     [B]
        mov     [Result],       ax
        ;вывод значения Result на экран
        mov     ax,     [Result]
        ;выводим содержимое регистра ax на экран
        mov     bx,     10              ;делитель (основание системы счисления)
        mov     cx,     0               ;количество выводимых цифр
        @@div:
                xor     dx,     dx      ;делим (dx:ax) на bx
                div     bx
                add     dl,     '0'     ;преобразуем остаток деления в символ цифры
                push    dx              ;и сохраняем его в стеке
                inc     cx              ;увеличиваем счётчик цифр
                test    ax,     ax      ;в числе ещё есть цифры?
        jnz     @@div                   ;да - повторить цикл выделения цифры
        @@show:
                mov     ah,     02h     ;функция ah=02h int 21h - вывести символ из dl на экран
                pop     dx              ;извлекаем из стека очередную цифру
                int     21h             ;и выводим её на экран
        loop    @@show                  ;и так поступаем столько раз, сколько нашли цифр в числе (cx)
 
        ;завершение программы
        int     20h
main    endp
 
; ввод 16-разрядного беззнакового числа
; при ошибке - выводится диагностическое сообщение и ввод повторяется
; на входе:
;   ds:[si] - строка с приглашением ко вводу числа
; на выходе
;   ax - число
GetUInt16       proc
        push    dx
        push    si
        ; ввод числа с клавиатуры (строки)
@@GetString:
        mov     ah,     09h             ;вывод строки приглашения ко вводу
        mov     dx,     si
        int     21h
 
        mov     ah,     0Ah             ;ввод строки
        lea     dx,     [KeyBuf]
        int     21h
 
        mov     ah,     [09h]           ;перевод курсора на новую строку
        lea     dx,     [CR_LF]
        int     21h
 
        ; преобразование строки в число
        push    si
        lea     si,     [KeyBuf+1]
        call    StrToUInt16
        pop     si
 
        ; проверка на ошибку преобразования строки в число
        jnc     @@GetUInt16_Ok
 
        ; если есть ошибка ввода - напечатать сообщение об ошибке
        mov     ah,     09h
        lea     dx,     [ErrorGetUInt16]
        int     21h
        jmp     @@GetString
@@GetUInt16_Ok:
        pop     si
        pop     dx
        ret
GetUInt16       endp
 
; преобразования строки в беззнаковое число 0...65535
; на входе:
;   ds:[si] - строка с числом
; на выходе:
;   ax - число
;   CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
StrToUInt16     proc
        push    bx
        push    cx
        push    dx
        push    si
 
        mov     cl,     ds:[si]                 ;в cx - длина строки для цикла
        xor     ch,     ch
        jcxz    @@Error                         ;если строка пустая - это ошибка
 
        inc     si
        xor     ax,     ax
 
        @@Loop:
                mov     bx,     10              ; умножаем результат (ax) на 10 ( (dx:ax)=ax*bx )
                mul     bx                      ; и при этом игнорируем старшее слово
                test    dx,     dx              ; но проверяем, результат на переполнение
                jnz     @@Error
 
                mov     bl,     [si]            ; Преобразуем следующий символ в число
                sub     bl,     '0'
                jb      @@Error                 ; сразу проверяем на принадлежность к цифрам
                cmp     bl,     9
                ja      @@Error
                add     ax,     bx
                jc      @@Error                 ; Если сумма больше 65535
 
                inc     si
 
        loop    @@Loop
 
        clc
        pop     si
        pop     dx
        pop     cx
        pop     bx
        ret
@@Error:
        xor     ax,     ax
        stc
        pop     si
        pop     dx
        pop     cx
        pop     bx
        ret
StrToUInt16     endp
 
end     main
Четвёртую программу создайте самостоятельно
0
ФедосеевПавел
Модератор
4732 / 2633 / 1051
Регистрация: 01.02.2015
Сообщений: 8,616
Записей в блоге: 1
09.11.2019, 19:49 12
программа вводит две переменные A и B, складывает две переменные A и B, сумму помещает в переменную Result, выводит содержимое Result на экран
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
.model tiny
 
.code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        A               dw      123
        B               dw      456
        Result          dw      987
        ;переменные для ввода и вывода
        KeyBuf          db      7, 0, 7 dup(0)      ;max,len,string,CR(0dh)
        CR_LF           db      0Dh, 0Ah, '$'
        PromptA         db      'Введите число A (0..999): ', '$'
        PromptB         db      'Введите число B (0..999): ', '$'
        ErrorGetUInt16  db      'Ошибка ввода числа', 0Dh, 0Ah, '$'
start:
        ;программа
        ; ввод числа A с клавиатуры (строки)
        lea     si,     [PromptA]
        call    GetUInt16
        mov     [A],    ax
        ; ввод числа B с клавиатуры (строки)
        lea     si,     [PromptB]
        call    GetUInt16
        mov     [B],    ax
        ;сложение переменных
        mov     ax,     [A]
        add     ax,     [B]
        mov     [Result],       ax
        ;вывод значения Result на экран
        mov     ax,     [Result]
        ;выводим содержимое регистра ax на экран
        mov     bx,     10              ;делитель (основание системы счисления)
        mov     cx,     0               ;количество выводимых цифр
        @@div:
                xor     dx,     dx      ;делим (dx:ax) на bx
                div     bx
                add     dl,     '0'     ;преобразуем остаток деления в символ цифры
                push    dx              ;и сохраняем его в стеке
                inc     cx              ;увеличиваем счётчик цифр
                test    ax,     ax      ;в числе ещё есть цифры?
        jnz     @@div                   ;да - повторить цикл выделения цифры
        @@show:
                mov     ah,     02h     ;функция ah=02h int 21h - вывести символ из dl на экран
                pop     dx              ;извлекаем из стека очередную цифру
                int     21h             ;и выводим её на экран
        loop    @@show                  ;и так поступаем столько раз, сколько нашли цифр в числе (cx)
 
        ;завершение программы
        int     20h
main    endp
 
; ввод 16-разрядного беззнакового числа
; при ошибке - выводится диагностическое сообщение и ввод повторяется
; на входе:
;   ds:[si] - строка с приглашением ко вводу числа
; на выходе
;   ax - число
GetUInt16       proc
        push    dx
        push    si
        ; ввод числа с клавиатуры (строки)
@@GetString:
        mov     ah,     09h             ;вывод строки приглашения ко вводу
        mov     dx,     si
        int     21h
 
        mov     ah,     0Ah             ;ввод строки
        lea     dx,     [KeyBuf]
        int     21h
 
        mov     ah,     09h             ;перевод курсора на новую строку
        lea     dx,     [CR_LF]
        int     21h
 
        ; преобразование строки в число
        push    si
        lea     si,     [KeyBuf+1]
        call    StrToUInt16
        pop     si
 
        ; проверка на ошибку преобразования строки в число
        jnc     @@GetUInt16_Ok
 
        ; если есть ошибка ввода - напечатать сообщение об ошибке
        mov     ah,     09h
        lea     dx,     [ErrorGetUInt16]
        int     21h
        jmp     @@GetString
@@GetUInt16_Ok:
        pop     si
        pop     dx
        ret
GetUInt16       endp
 
; преобразования строки в беззнаковое число 0...65535
; на входе:
;   ds:[si] - строка с числом
; на выходе:
;   ax - число
;   CY - флаг переноса (при ошибке - установлен, иначе - сброшен)
StrToUInt16     proc
        push    bx
        push    cx
        push    dx
        push    si
 
        mov     cl,     ds:[si]                 ;в cx - длина строки для цикла
        xor     ch,     ch
        jcxz    @@Error                         ;если строка пустая - это ошибка
 
        inc     si
        xor     ax,     ax
 
        @@Loop:
                mov     bx,     10              ; умножаем результат (ax) на 10 ( (dx:ax)=ax*bx )
                mul     bx                      ; и при этом игнорируем старшее слово
                test    dx,     dx              ; но проверяем, результат на переполнение
                jnz     @@Error
 
                mov     bl,     [si]            ; Преобразуем следующий символ в число
                sub     bl,     '0'
                jb      @@Error                 ; сразу проверяем на принадлежность к цифрам
                cmp     bl,     9
                ja      @@Error
                add     ax,     bx
                jc      @@Error                 ; Если сумма больше 65535
 
                inc     si
 
        loop    @@Loop
 
        clc
        pop     si
        pop     dx
        pop     cx
        pop     bx
        ret
@@Error:
        xor     ax,     ax
        stc
        pop     si
        pop     dx
        pop     cx
        pop     bx
        ret
StrToUInt16     endp
 
end     main
0
elia_ches
0 / 0 / 1
Регистрация: 27.11.2017
Сообщений: 5
10.11.2019, 00:25  [ТС] 13
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Всем спасибо за помощь в решении. Я смогла сделать прогу
0
ФедосеевПавел
Модератор
4732 / 2633 / 1051
Регистрация: 01.02.2015
Сообщений: 8,616
Записей в блоге: 1
10.11.2019, 00:32 14
elia_ches, а поделитесь и похвастайтесь решением!
И мы все за вас порадуемся.
0
10.11.2019, 00:32
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.11.2019, 00:32

Ввести с клавиатуры массив из 10 целых чисел, посчитать сумму и вывести на экран
Ввести с клавиатуры массив из 10 целых чисел, посчитать сумму и вывести на экран

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

Или воспользуйтесь поиском по форуму:

14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.