Доброго времени суток!) У меня проблемы с ассемблером.. Программа есть, но она подсчитывает сумму четных элементов. Не могли бы вы мне объяснить, как сумму четных изменить на сумму не нулевых? Конечно, можно было бы просто подсчитать сумму всех элементов массива, но это не канает =\
| Код | ASSUME CS:kom, SS:stek, DS:dan ; описание сегментов ;сегмент кода kom SEGMENT ; сегмент данных dan SEGMENT mas DW 2,1,0,2,4,0,1,3,6,1,4,1 ; массив чисел koli DW 12 ; количество элементов массива sum DW ? ; переменная для хранения суммы ind DW ? ; переменная для хранения индекса этого элемента dan ENDS
; главная функция main PROC FAR MOV AX,dan ; записываем адрес данных в ax MOV DS,AX ; записываем адрес данных из ax в сегмент данных MOV AX,stek ; записываем адрес стека в ax MOV SS,AX ; записываем адрес стека из ax в сегмент стека PUSH BP ; сохраняем старый адрес возврата MOV BP,SP ; BP=SP адрес кадра стека caller: MOV AX, koli ; количество элементов - счетчик цикла PUSH AX ; вталкиваем в стек LEA BX,mas ; адрес массива в регистр BX PUSH BX ; вталкиваем в стек CALL summa ; вызов функции поиска четных элементов
vyvod: MOV AX,sum ; берем значение суммы PUSH AX ; отправляем в стек MOV AX,10 ; задаем базу – десятеричная система PUSH AX ; отправляем в стек базу CALL kod ; вызываем функцию вывода чисел MOV BX,' ' ; берем символ PUSH BX ; заталкиваем его в стек CALL putchar ; вызываем функцию вывода символа MOV AX,10 ; выводим его как десятеричное число PUSH AX ; для этого отправляем как параметр CALL kod ; функции вывода числа exit: xor AX,AX ; обнуляем ax MOV AH,4cH ; выход в DOS INT 21H ; передача управления в DOS main ENDP
; процедура поиска четных элементов массива summa PROC ; объявление процедуры ike EQU -2[BP] ; локальная переменная хранится в стеке PUSH BP ; сохранить старое значение BP в стек MOV BP,SP ; BP=SP - устанавливаем указатель на базу b1: mov CX,6[BP] ; количество элементов массива mov BX,4[BP] ; адрес массива mov si,0 ; индекс - номер элемента - храним в si mov sum,0 b2: mov dx,BX[si] ; текущий элемент массива в dx cmp dx,0 ; сравниваем текущий с 0 jbe b4 ; <= тогда в конец цикла, к следующему числу and dx,1 ; проверка остатка от деления на 2 cmp dx, 0 jne b4 ; != тогда в конец цикла, к следующему числу b3: mov ax, sum add ax,BX[si] mov sum, ax ; увеличиваем сумму b4: add si,2 ; увеличиваем индекс на длину элемента dec cx ; уменьшаем счетчик цикла jcxz vyhod ; счетчик обнулен? да-выход jmp b2 ; нет - повторить цикл сравнения vyhod: POP BP ; восстанавливаем BP RET 6 ; возврат с удалением параметров из стека summa ENDP
; процедура вывода строчного символа putchar PROC PUSH BP ; сохранить старое значение BP в стек PUSH AX ; PUSH DX ; MOV BP,SP ; BP=SP MOV DL,8[BP] ; MOV AH,2 ; 2 - вывод символа на экран INT 21H ; передача управления в DOS POP DX ; вытолкнуть из стека DX POP AX ; вытолкнуть из стека AX POP BP ; восстанавливаем адрес возврата RET 2 ; putchar ENDP
; процедура вывода числа в десятеричной форме kod PROC x EQU 6[BP] ; локальная переменная x в стеке baza EQU 4[BP] ; локальная переменная baza в стеке y EQU -2[BP] ; локальная переменная y в стеке PUSH BP ; сохранить старое значение BP MOV BP,SP ; BP=SP адрес кадра стека SUB SP,2 ; SP=SP-2 MOV AX,x ; CWD IDIV WORD PTR baza MOV y,AX CMP AX,0 JE m1 MOV AX,y PUSH AX
CALL kod ; рекурсия m1: MOV AX,x ; CWD IDIV WORD PTR baza ADD DX,'0' ;записываем код нуля в DX PUSH DX ; вталкиваем DX CALL putchar ; вызов процедуры вывода символа на экран ADD SP,2 ; переходим на 1 вниз POP BP ; восстановление адреса возврата RET 6 ; возврат с удалением параметров (4 ячейки) kod ENDP kom ENDS ; завершение сегмента кода
; сегмент стека stek SEGMENT STACK DW 1000 DUP(?) ; создается пустая область из 1000 слов стек ; dnost EQU $ ; символ конца строки stek ENDS END main
|
|