Консультация № 189189
14.04.2016, 13:05
0.00 руб.
0 3 1
Здравствуйте! У меня возникли сложности с таким вопросом:

Написать программу для нахождения суммы элементов массива

Обсуждение

давно
Посетитель
7438
7205
14.04.2016, 13:16
общий
Адресаты:
Как задается массив? В тексте, вводить с консоли, случайно, с файла...?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
400201
1
14.04.2016, 13:19
общий
случайно
давно
Посетитель
7438
7205
14.04.2016, 16:20
общий
это ответ
Здравствуйте, sergey-filippov1997!
Вот Вам программа. Будут вопросы - спрашивайте в мини-форуме
[code lang=asm h=200]
;Нахождение суммы элементов массива

.model small
.code
.startup

call srand ;Инициируем генератор псевдослучайных чисел

call GetNum ;Введем размерность массива
mov N, ax ;сохраним
;выделим место под массив в стеке
shl ax, 1 ;для слов надо в 2 раза больше байт
sub sp, ax ;выделяем место в стеке
mov bp, sp ;адрес начала массива в BP

call SetVector ;заполним массив случайными числами

call PrintVector ;выведем на экран массив

lea dx, sSum
mov ah, 9
int 21h

call CalcSum ;считаем сумму

call PrintNum

mov ah, 0 ;ждем нажатия на клавишу
int 16h

mov ax, N ;подкорректируем стек (для порядка)
mul ax ; вообще говоря, можно не делать...
shl ax, 1
add sp, ax

.exit 0 ;выход в ДОС

stoi proc ;преобразование строки [si] в число AX
xor bx, bx ;здесь будем стоить число
xor cx, cx ;счетчик разрядов
stoi_next:
lodsb ;очередной символ
cmp al, 0dh ;конец стоки?
je stoi_eol
cmp al, '0'
jb stoi_sep ;любая нецифра - разделитель
cmp al, '9'
ja stoi_sep
push ax ;сохраним новый разряд
mov ax, 10
mul bx ;умножим старшие на 10
pop dx ;новый
and dx, 0fh ;'0'-'9' -> 0-9
add ax, dx ;добавляем новый разряд
cmp ax, 255 ;ждем число <=255
ja numError ;больше - ошибка!
mov bx, ax ;сохраняем
inc cx ;считаем
jmp stoi_next ;продолжаем
stoi_sep: ;встретили разделитель
jcxz stoi_next ;были только разделители - на продолжение
; иначе - конец числа и выходим
stoi_eol: ; если числа нет и встретили 0dh - конец строки
mov ax, bx ;число возвращаем в ax
clc ;признак того, что все ок
ret
numError:
stc ;признак ошибки
ret
stoi endp

GetNum proc ;ввод N чисел
lea dx, sEnter
mov ah, 9
int 21h ;приглашение на ввод числа

lea dx, max ;вводим строку с числами
mov ah, 0ah
int 21h
lea si, sBuf ;числовая строка

call stoi ;[si] в число ax
jc GetNum ;C=1 число > 255
test ax, ax
je GetNum

push ax
mov ah, 2
mov dl, 0ah
int 21h
pop ax
ret
GetNum endp

PrintNum proc ;вывод знакового числа в AX на экран
push ax ;сохраним выводимое значение
;выведем знак ' '/'-'
mov dl, ' ' ;считаем пока, что число положительное
test ax, ax ;проверяем число
jge print_sign ;для положительного - на вывод знака
;для отрицательного
pop ax ;уберем из стека число
neg ax ;найдем модуль числа!
push ax ;и сохраним в стеке уже положительное число!
mov dl, '-' ;знак отрицательного числа

print_sign:
mov ah, 2 ;выводим знак
int 21h
pop ax ;AX - модуль числа, т.е. строго положительное

;найдем все разряды числа и сохраним их в стеке в обратном порядке!
xor cx, cx ;счетчик разрядов
mov bx, 10 ;будем делить на 10 (10-ричная с.с.!)
digits_loop: ;цикл нахождения разрядов
xor dx, dx ;готовимся к делению dx:ax/bx
div bx ;dx - остаток от dx:ax/bx, ax - частное
push dx ;остаток - очередной десятичный разряд,
; сохраняем в стеке
inc cx ;считаем
test ax, ax ;проверим число
jne digits_loop ;повторяем, пока есть еще разряды
print_loop: ;выводим разряды в обратном порядке
pop dx ;очередной разряд
or dl, '0' ;число в ASCII-код
mov ah, 2 ;выводим символ
int 21h
loop print_loop ;для всех найденных разрядов, количество в CX
ret
PrintNum endp

PrintVector proc
lea dx, sSourceVector ;строка - заголовок
mov ah, 9
int 21h

xor si, si
mov cx, N
PrintVector_loop:
push cx
mov ax, [bp+si]
call PrintNum
mov dl, ' '
mov ah, 2
int 21h
add si, 2
pop cx
loop PrintVector_loop
mov dl, 0dh
mov ah, 2
int 21h
mov dl, 0ah
mov ah, 2
int 21h
ret
PrintVector endp

CalcSum proc
xor si, si
mov cx, N
xor ax, ax
CalcSum_loop:
add ax, [bp+si]
add si, 2
loop CalcSum_loop
ret
CalcSum endp

;заполнение массива (адрес в BP) случайными знаковыми числами
SetVector proc
mov di, 200 ;будем заполнять числами [-100;99]
mov cx, N ;число элементов вектора
xor si, si ;индекс очередного элемента
SetVector_loop: ;цикл по всем элементам
call rnd ;получаем очередно случайное число
xor dx, dx
div di ;делим на "размах" чисел
sub dx, 100 ;отнимаем от остатка середину, получаем знаковое число!
mov [si+bp], dx ;сохраняем!
add si, 2 ;индексируем следующий элемент
loop SetVector_loop ;циклим
ret
SetVector endp

srand proc ;инициализация генератора псевдослучайных чисел
mov ah, 2ch
int 21h ;возьмем текущее время
mov al, dl ;сотые секунды
mul dh ;умножаем на секунды
mov rand_value, ax ;сохраним, как текущее
ret
srand endp

;простые числа, необходимые для простейшего генератора псевдослучайных чисел
a equ 13013
c equ 16383

;rand = ((a * rand) / 65536) + c
rnd proc
mov ax, a
mul rand_value
add ax, c
mov rand_value, ax
ret
rnd endp

.data
sEnter db "Enter N = $"
sSourceVector db "Source vector = $"
sSum db "Sum = $"
max db 128
cnt db ?
sBuf db 128(?)
N dw ?
rand_value dw ?
end
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа