Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Среднее арифметическое четных элементов массива

Вопрос:
расчета среднего арифметического значения положительных элементов в одномерном массиве, имеющих четные индексы.

Ответ:
Пример окна программы:
-7  -115  49  37  -87  -3  97  21  89  109
Среднее арифметическое равно: 78
Press any key ...
; среднее арифметическое положительных четных
.model tiny ; COM-файл нежно получить
.386
.code
org 100h
start:
   mov ax, 3
   int 10h
   
; Не написали, как вводить массив - заполню псевдослучайными (на автомат!!)
; прочитаем текущие тики в качестве затравки
; получается типа RANDOMIZE в Паскале   

	mov  CX, 50 ; будем использовать цикл - настроим СХ
	push es
	push 040h
	pop  es
	mov  DX, es:[6ch]
	pop  es

; заполнение
          lea si, ar	
          mov cx, ar_len
fill_random:
 	imul DX, 4e35h
	mov  [si], dl
	inc  SI
          LOOP fill_random
; покажем, воспринимая числа как знаковые
          lea si, ar
          mov cx, ar_len
          cld
@@_show_next:
          lodsb
          cbw ; я написал процедуру для слов, а здесь байты -> Convert Byte to Word
          CALL WriteWordDEC_signed
          ; два пробела для разделения
          mov al, ' '
          int 29h
          int 29h
        LOOP @@_show_next  
        
; вычисление суммы
          lea si, ar
          mov cx, ar_len
          shr cx, 1  ; эффективное деление на 2        
          xor bx, bx ; будет сумма  
@@_next:
          lodsb        
          or al, al
          js negative ; знак устновлен - отрицательное
              cbw
              add summ, ax
              inc bx
negative:          
          lodsb ; прочитываем зря нечетное
         LOOP @@_next 
 
         or  bx, bx
         jnz mid
            lea dx, msg_no_pos
            mov ah, 9
            int 21h
            jmp @@_exit
mid:          
         lea dx, msg_mid
         mov ah, 9
         int 21h
         
         mov  ax, summ
         xor  dx, dx
         idiv bx
         CALL WriteWordDEC_signed

@@_exit:         
  lea dx, PressKey
  mov ah,9
  int 21h

  xor ax, ax
  int 16h

  int 20h

writeWordDEC proc near
; вывод на экран слова в AX, воспринимается как беззнаковое
 push ax
 push bx
 push dx
 push cx
   mov bx, 10
   xor cx, cx
@@1:
   xor dx, dx
   div  bx
   push dx
   inc cx
   or ax, ax
   jnz @@1
 @@2:
   pop ax
   add al, '0'
   int 29h
   LOOP @@2    
 pop  cx
 pop  dx
 pop  bx
 pop  ax
 ret
writeWordDEC endp

WriteWordDEC_signed proc
; вывод на экран слова в AX как знакового
 or ax, ax
 jns @@_no_sign 
   push ax
   mov al, '-'
   int 29h
   pop ax
   neg ax ; изменение знака на +
@@_no_sign:
 CALL writeWordDEC     
 ret
WriteWordDEC_signed endp   

PressKey db   13,10,'Press any key ...$'
msg_mid  db   13,10,'Среднее арифметическое равно: $'
msg_no_pos db 13,10,'Положительных с четным индексом нет$'

summ   dw    0 ; размер больше байта для суммы
ar_len equ 10 ; так объявляются константы - здесь длина массива
ar     db    ar_len dup (?)  
end start

   Вперёд
   Содержание