Макроопределение для вычисления суммы четных элементов массива - Assembler
Формулировка задачи:
Составить макроопределение вычисления суммы четных элементов массива чисел а1, а2, ..., an. Используя это макроопределение, найти сумму четных элементов каждого из трех массивов а1, а2,... а7; b1, b2,... b7; c1, c2, ...c7.
написал код а он не работает! исправить не получается! или я неправильно все сделал!
seach macro Local cikl, l1, m1, n1, b1, konec xor dx,dx mov bx,offset string+2 mov di,bx cikl: mov al,[bx] cmp al,13 je m1 cmp al,20h ;сравниваем с пробелом je m1 test dx, dx jnz l1 xor cx,cx inc dx mov si,bx ; l1: inc cx jmp b1 m1: mov byte ptr [bx], '$' test dx,dx jz n1 xor dx, dx cmp cx,min jg n1 mov min,cx mov di,si ; n1: cmp al,13 je konec b1: inc bx jmp cikl konec: mov dx,offset crlf mov ah,9 int 21h mov dx,di endm stack1 segment db 200h dup (?) stack1 ends data segment string db 100,?,100+1 dup ('$') min dw 32767 crlf db 13,10,'$' data ends code segment start: assume cs:code,ds:data mov ax, data mov ds, ax mov ah,0ah lea dx,string int 21h seach string, dx mov ah, 09h int 21h mov ah, 10h int 16h mov ax, 4c00h int 21h code ends end start
Решение задачи: «Макроопределение для вычисления суммы четных элементов массива»
textual
Листинг программы
macro SEARCH { XOR DI,DI ; здесь будет результат. пока DI = 0 XOR AX,AX ; сюда будем читать числа с массива MOV SI,array ; адресс массива в SI (для LODSB) MOV CX,length ; CX = кол-во элементов в массиве @1: LODSB ; читаем байт с массива TEST AL,1 ; проверяем младший бит числа на нуль JNZ uneven ; если не нуль - число нечётное ADD DI,AX ; прибавляем чётное число к DI uneven: LOOP @1 } ; сл.элемент массива.. ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн ORG 100h JMP start mess0 DB 13,10,' Сумма чётных элементов: $' array DB 0, 58, 250, 11, 19, 81, 60, 103, 79, 92 length = $ - array ; длина массива start: MOV AH,9 ; выводим мессагу MOV DX,mess0 INT 21h SEARCH ; зовём наш макрос (результат в DI) MOV AX,DI ; результ в AX (параметр для HEX2ASC) MOV BX,10 ; BX = система счисления для вывода CALL HEX2ASC ; переводим число АХ в символы ; ..и выводим результат на экран exit: XOR AX,AX ; выход по клавише! INT 16h INT 20h ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн ;//========= ФУНКЦИЯ ВЫВОДИТ НА ЭКРАН В РАЗЛИЧНЫХ СС =========================| HEX2ASC: PUSHA ; перевод из HEX в ASCII и вывод на экран XOR CX,CX ; при вызове: BX = система счисления, AX = число isDiv: XOR DX,DX ; очистим место под остаток DIV BX ; разделим AX на фактор системы счисления PUSH DX ; сохраняем остаток от деления INC CX ; увеличим счётчик разрядности цифры OR AX,AX ; это последняя цифра?! JNZ isDiv ; нет - читаем следующую.. isOut: POP AX ; снимаем со-стека остаток в обратном порядке CMP AL,9 ; проверка на десятичную цифру JLE noHex ; меньше/равно? значит это не HEX-цифра ADD AL,7 ; коррекция для HEX.. noHex: ADD AL,30h ; переводим цифру в символ INT 29h ; выводим её на экран LOOP isOut ; ^^.. и мотаем цикл CX-раз. POPA RET
Объяснение кода листинга программы
- Макроопределение SEARCH вычисляет сумму четных элементов массива.
- Перед вызовом макроса, в регистре AX содержится количество элементов в массиве, а в регистре SI - адрес массива.
- Макрос начинает работу с инициализации двух регистров: XOR DI,DI - здесь будет результат, XOR AX,AX - сюда будем читать числа с массива.
- Далее макрос перемещает адрес массива в SI (для LODSB), а кол-во элементов в CX.
- Затем начинается цикл, который состоит из двух ветвей:
- Если младший бит числа, прочитанного с массива, не равен нулю, то число нечетное и мы переходим к следующей итерации цикла.
- Если младший бит равен нулю, то число четное и мы прибавляем его к DI.
- После окончания цикла, результат содержится в DI.
- Функция HEX2ASC выводит число, прочитанное с массива в разных системах счисления.
- Функция начинается с инициализации регистра CX, который используется как счетчик разрядности цифры.
- Затем происходит деление AX на фактор системы счисления, и остаток от деления сохраняется в DX.
- Далее увеличивается счетчик разрядности цифры, и если это последняя цифра, то происходит вывод ее на экран.
- Если это не последняя цифра, то она снимается со стека в обратном порядке и выводится на экран.
- Если число больше или равно 10, то оно считается десятичной цифрой и выводится на экран после коррекции для HEX.
- Если число меньше 10, то оно считается символом и выводится на экран после добавления 30h.
- После вывода всех цифр, функция возвращает управление.