Вариант 5. Вывести на экран
сумму элементов целочисленного массива,
предварительно изменив произвольным
образом элементы массива при помощи команд
побитовой обработки.
- .model tiny
- .data
|
- ar1 dw 3,4,2,1,5,4,2,7 ;8 элементов
|
- ar2 dw 15,34,13,35,12,57,0;7 элементов
|
- ar3 dw 1,4,15,3,7,5,8,68,5;9 элементов
|
- mes db 'summa elementov massiva ravna ','$'
|
|
- ;сегмент кода
|
- .code
|
|
|
- .386
|
- org 100h
|
- start:
|
- movzx ecx,len ;для цикла заносим
длину массива
|
- shr ecx,1 ;так как длина в словах
делим на 2
|
- dec cl ;сравниваем со следующим,
значит на 1 меньше
|
- xor esi,esi ;начальное значение
индекса 0
|
- lea ebx,massiv ;заносим адрес массива
|
- l1:
|
- mov ax,[ebx+esi*2] ;считываем первый элемент
|
- and ax,1000000000000000b ;проверяем старший
бит - знак
|
- mov sign,ax ;сохраняем его
|
- mov dx,[ebx+esi*2+2] ;считываем второй элемент
|
- and dx,1000000000000000b
|
- cmp dx,sign ;сравниваем знаки
|
- jmp l2
|
- l2:
|
- inc esi ;увеличиваем индекс
|
- loop l1
|
- ;------------------------
|
- ;блок вывода исходного массива после обработки
|
- ;------------------------
|
- movzx ecx,len ;для вывода нужны все
элементы
|
- shr ecx,1
|
- xor esi,esi
|
- l3:
|
- mov ax,[ebx+esi*2] ;считываем элемент
|
- push ax
|
- xchg ah,al
|
- call print_all ;вывод старшей цифры
|
- pop ax
|
- call print_all ;вывод младшей цифры
|
- inc esi ;увеличиваем индекс
|
- loop l3
|
- mov dx,offset ctrl ;адрес строки перевода
|
- mov ah,09h ;перевести строку
|
- int 21h
|
- ;------------------------
|
- ;Блок вычисления максимального и среднего арифметического
|
- ;максимального и последнего элемента
|
- ;------------------------
|
- movzx ecx,len
|
- shr ecx,1
|
- dec cl
|
- push ebx ;адрес массива
|
- push ebx
|
- mov ax,[ebx] ;считываем первый элемент
|
- add ebx,2 ;переходим к следующему
|
- l6:
|
- cmp ax,[ebx] ;сравниваем со следующим
|
- jg l5 ;больше?
|
- mov ax,[ebx] ;нет - заносим в регистр
|
- l5:
|
- add ebx,2 ;да - переходим к следующему
|
- loop l6
|
- pop ebx
|
- push eax ;это наибольший элемент
|
- movzx eax,len
|
- sub eax,2
|
- add ebx,eax ;перемещаемся на последний
элемент
|
- pop eax
|
- add ax,[ebx] ;добавляем к наибольшему
|
- push ax
|
- and ax,1000000000000000b ;определяем знак
|
- mov sign,ax
|
- pop ax
|
- shr ax,1 ;делим на 2 - среднее
арифметическое двух чисел
|
- or ax,sign ;устанавливаем знак
|
- cmp sign,1000000000000000b ;знак минус?
|
- jne l4 ;нет - идем дальше
|
- dec ax ;да - увеличиваем среднее
|
- l4:
|
- pop ebx
|
- lea ebp,massiv1 ;заносим адрес нового
массива
|
- push ebp
|
- movzx ecx,len ;заносим длину исходного
массива
|
- shr ecx,1
|
- l8:
|
- mov dx,[ebx] ;считываем элемент
исходного массива
|
- cmp dx,ax ;он больше среднего
арифметического?
|
- jle l7 ;нет - идем дальше
|
- mov [ebp],dx ;да - заносим его в новый
массив
|
- add ebp,2 ;переводим указатель
на следующий элемент нового массива
|
- inc len1 ;изменяем длину нового
массива
|
- l7:
|
- add ebx,2 ;переходим к следующему
элементу исходного массива
|
- loop l8
|
- pop ebp
|
- movzx ecx,len1 ;длина нового массива
|
- test ecx,ecx ;она равна нулю?
|
- jz l10 ;да - выход
|
- l9:
|
- mov ax,[ebp] ;нет - считываем
|
- push ax ;и выводим
|
- xchg ah,al ;этот уже проходили
|
- call print_all
|
- pop ax
|
- call print_all
|
- add ebp,2
|
- loop l9
|
- l10:
|
- ret
|
- ;------------------------
|
- ;Блок вывода цифр. Выводит в 16-ричной системе.
|
- ;Отрицательные выводит согласно 16-ричной системы.
|
- ;------------------------
|
- print_all:
|
- mov dh,al ;сохраняем
|
- and dh,0Fh ;младшую цифру
|
- shr al,4
|
- call print_n ;вывод старшей цифры
|
- mov al,dh ;восстанавливаем младшую
и вывод
|
- print_n:
|
- cmp al,10
|
- sbb al,69h
|
- das
|
- mov dl,al
|
- mov ah,2
|
- int 21h
|
- ret
|
|
- massiv dw 1,-2,3,4,5,6,7,11,9,10 ;задан произвольно
с произвольным количеством
|
- len db $-massiv
|
- sign dw ?
|
- max dw ?
|
- ctrl db 0Dh,0Ah,'$'
|
- len1 db 0
|
- massiv1:
- ;ссылаем на сегмент данных
|
- mov ax, @data
|
- mov ds, ax
|
- ;ициализация переменных
|
- xor bx,bx ;ax=0
|
- mov cx,8 ;cx=8
|
- xor si,si ;si=0
|
|
- ;цикл, суммирующий элементы массива
|
- cycle:
|
- add bx,ar1[si] ;ax=ax+ar[si]
|
- inc si ;si++
|
- loop cycle ;повторяем цикл
|
- ;вывод строки
|
- string:
|
- mov ah,09h ;команда на вывод
|
- mov dx,offset mes ;помещаем строку
|
- int 21h ;вызываем прерывания
|
|
- xor cx,cx
|
- xor ax,ax
|
- xor dx,dx
|
- ;вывод числа
|
- mov ax,bx ;ax=bx
|
- push -1 ;Сохраним признак конца
числа
|
- mov cx,10 ;Делим на 10
|
- repeat:
|
- xor dx,dx ;Очистим регистр dx
|
- div cx ;Делим
|
- push dx ;Сохраним цифру
|
- cmp ax,0 ;Остался 0? (оптимальнее or ax,ax)
|
- jne repeat ;нет -> продолжим
|
- mov ah,2h
|
- digit:
|
- pop dx ;Восстановим цифру
|
- cmp dx,-1 ;Дошли до конца -> выход {оптимальнее: or dx,dx jl ex}
|
- je exit
|
- add dl,'0' ;Преобразуем число
в цифру
|
- int 21h ;Выведем цифру на экран
|
- jmp digit ;И продолжим
|
|
- exit:
|
- mov ax, 4C00h
|
- int 21h
|
|
- end start
|