Макроопределение для вычисления суммы четных элементов массива - 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

Объяснение кода листинга программы

  1. Макроопределение SEARCH вычисляет сумму четных элементов массива.
  2. Перед вызовом макроса, в регистре AX содержится количество элементов в массиве, а в регистре SI - адрес массива.
  3. Макрос начинает работу с инициализации двух регистров: XOR DI,DI - здесь будет результат, XOR AX,AX - сюда будем читать числа с массива.
  4. Далее макрос перемещает адрес массива в SI (для LODSB), а кол-во элементов в CX.
  5. Затем начинается цикл, который состоит из двух ветвей:
    • Если младший бит числа, прочитанного с массива, не равен нулю, то число нечетное и мы переходим к следующей итерации цикла.
    • Если младший бит равен нулю, то число четное и мы прибавляем его к DI.
  6. После окончания цикла, результат содержится в DI.
  7. Функция HEX2ASC выводит число, прочитанное с массива в разных системах счисления.
  8. Функция начинается с инициализации регистра CX, который используется как счетчик разрядности цифры.
  9. Затем происходит деление AX на фактор системы счисления, и остаток от деления сохраняется в DX.
  10. Далее увеличивается счетчик разрядности цифры, и если это последняя цифра, то происходит вывод ее на экран.
  11. Если это не последняя цифра, то она снимается со стека в обратном порядке и выводится на экран.
  12. Если число больше или равно 10, то оно считается десятичной цифрой и выводится на экран после коррекции для HEX.
  13. Если число меньше 10, то оно считается символом и выводится на экран после добавления 30h.
  14. После вывода всех цифр, функция возвращает управление.

Оцени полезность:

8   голосов , оценка 4 из 5
Похожие ответы