Найти среднее значение элементов массива - Assembler
Формулировка задачи:
.model small
.stack 100h
.data
array db 65000 dup (200)
mas_len EQU ($ - array)
string1 db "Srednee znachenie el-ov massiva: $"
.code ;начало сегмента кода
start:
mov ax, @data ;инициализация сегмента данных
mov ds, ax ;сохраняем адрес @data в регистре сегмента данных
mov ah, 09h
lea dx, string1
int 21h
lea si, array ;помещаем адрес начала массива в si
mov cx, mas_len ;поместили длину массива в cx
m:
xor ax, ax
mov al, [si] ;в ax поместили то что лежит по адресу si(первый элемент)
cwd
add bx, ax ;в bx положили ax
inc si ;переход к след э-ту
loop m
mov ax, bx
mov bx, mas_len
div bx
; --- Чтобы вывести число из ax нам нужно перевести его в десятичную систему -------
; --- счисления. -------
; --- Для этого мы будем делить его на 10 и записывать остаток в стек -------
; --- таким образом в стеке окажутся все цифры числа в обратном порядке. -------
; --- В строке 162 операция cwd применена для расширения операции деления -------
; --- так после применения этой операции частное от деления будет храниться -------
; --- в ax, а остаток в dx -------
; ----------------------------------------------------------------------------------
xor cx,cx
mov bx,10
m1:
xor dx,dx
div bx
; Делим число на основание сс. В остатке получается последняя цифра.
; Сразу выводить её нельзя, поэтому сохраним её в стэке.
push dx
inc cx
; А с частным повторяем то же самое, отделяя от него очередную
; цифру справа, пока не останется ноль, что значит, что дальше
; слева только нули.
test ax, ax
jnz m1
mov ah,2
EndGet:
pop dx ; собственно сам вывод на экран. по очереди c конца
add dl, '0'
; цифры из стека(старшие разряду в начале мл. в конце)
int 21h
loop EndGet ; повторяем пока цифры не кончаться
; возвращаем в bx то что забрали
mov ax, 4c00h
mov dl, 0ah
int 21h
end startРешение задачи: «Найти среднее значение элементов массива»
textual
Листинг программы
mov bx, 0 ;результат сумирования будет в регистровой паре (di:bx) mov di, 0 lea si, array mov cx, mas_len @@For: mov al, [si] add si, 1 ;на размер элемента массива в байтах cbw ;преобразуем байт из al в двойное слово в регистровой паре (dx:ax) cwd add bx, ax ;суммируем регистровые пары adc di, dx loop @@For
Объяснение кода листинга программы
- Устанавливается начальное значение счетчика суммы в
0с помощью командыmov bx, 0, а также устанавливается начальное значение регистраdiв0с помощью командыmov di, 0. - Вычисляется адрес начала массива и сохраняется в регистре
siс помощью командыlea si, array. - Загружается длина массива в регистр
cxс помощью командыmov cx, mas_len. - Начинается цикл обработки элементов массива с помощью метки
@@For. - Загружается значение текущего элемента массива в регистр
alиз ячейки, адрес которой находится в регистреsi. - Увеличивается адрес в регистре
siна размер элемента массива в байтах с помощью командыadd si, 1. - Производится расширение байта из регистра
alв двойное слово в регистровой паре (dx:ax) с помощью командыcbw. - Производится расширение слова из регистра
axв двойное слово в регистровой паре (dx:ax) с помощью командыcwd. - Вычисляется сумма текущего элемента массива с текущим значением в регистровой паре (di:bx) и сохраняется в регистре
bxс помощью командыadd bx, ax, а также производится перенос в регистрdiс помощью командыadc di, dx. - Выполняется повторение цикла, уменьшая значение счетчика цикла в регистре
cxс помощью командыloop @@For. Данный код вычисляет сумму элементов массива и сохраняет её в регистровой паре (di:bx) при условии, что элементы массива представляют собой 16-битные целые числа.