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

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

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

	.stack	256

print	macro	str
	push	ax
	push	dx
	mov	ah,9
	lea 	dx,str
	int	21h
	pop	dx
	pop	ax
	endm

	.data
	cr = 0dh
	lf = 0ah
string		db	255, 0, 255 dup (?)
errmsg		db	'error: illegal symbol'
crlf		db	cr,lf,'$'
negflag		dw	?

msga		db	cr,lf,'a=$'
msgn		db	cr,lf,'n=$'
msgc		db	cr,lf,	'c=$'

a		dw	100 dup(?)
n		dw	?
c		dw	?

	.code

IntegerOut	proc
	push	ax
	push	bx
	push	cx
	push	dx
	xor	cx,cx
	mov	bx,10
	cmp	ax,0
	jge	om
	neg	ax
	push	ax
	mov	ah,2
	mov	dl,'-'
	int	21h
	pop	ax
om:	inc	cx
	xor	dx,dx
	div	bx
	push	dx
	or	ax,ax
	jnz	om
om1:	pop	dx
	add	dx,'0'
	mov	ah,2
	int	21h
	loop	om1
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
IntegerOut	endp

IntegerIn	proc
	push	dx
	push	si
	mov	ah,0ah
	lea	dx,string
	int	21h
	xor	ax,ax
	lea	si,string+2
	mov	negflag,ax
	cmp	byte ptr [si],'-'
	jne	im2
	not	negflag
	inc	si	
	jmp	im3
im2:     cmp	byte ptr [si],'+'
	jne	im3
	inc	si
im3:	cmp	byte ptr [si],cr
	je	iex1
	cmp	byte ptr [si],'0'
	jb	ier
	cmp	byte ptr [si],'9'
	ja	ier
	mov	bx,10
	mul	bx
	sub	byte ptr [si],'0'
	add	al,[si]
	adc	ah,0
	inc	si
	jmp	im3
ier:	lea 	dx,errmsg
	mov	ah,9
	int	21h
	jmp	IntegerIn
iex1:	cmp	negflag,0
	je	iex
	neg	ax
iex:	push	ax
	mov	ah,9
	lea	dx,crlf
	int	21h
	pop	ax
	pop	si
	pop	dx
	ret
IntegerIn	endp

start:	mov	ax,@data
	mov	ds,ax

	print	msgn
	call	IntegerIn
	mov	n,ax

	print	msga
	mov	cx,n
	lea	si,a
m1:	push	cx
	push	si
	call	IntegerIn
	pop	si
	pop	cx
	mov	[Si],ax
	add	si,2
	Loop	m1

вот с этого места надо поменять
	print	msga
	Lea	Si,a
    Mov	Cx,n
m2: Push Cx
    Lea Si,a
    Mov Cx,n
m3: Mov	Ax,[Si]
    ; Mov	Bx,2[Si]
    ; Cmp	Ax,Bx
    jns	m4 
	Add	Si,4	;если 5 то считаем
m4: add	[si],Ax
    ; Mov	2[Si],Ax
	Loop 	m3
	Pop 	Cx
	Loop	m2
	mov c,si
	
	Print	msga		;вывод массива
	mov	Cx,n
	Lea	Si,a
	mov	Ax,[c]
	Push	Cx
	Push	Si
	Call	integerOut
	Pop	Si
	Pop	Cx
	
	
	
	
        mov	ah,4ch
	int	21h
	end	start

Ответ:
Подправленная программа в приложении. Единственный момент, на который хочется обратить внимание: при расчете среднего арифметического делим сумму на число сложенных элементов. Так вот, при делении теряем остаток от деления. Надеюсь, это не принципиально...
;Найти среднее арифметическое положительных элементов, с четными номерами.

.model	small

	.stack	256

print	macro	str
	push	ax
	push	dx
	mov	ah,9
	lea 	dx,str
	int	21h
	pop	dx
	pop	ax
	endm

	.data
	cr = 0dh
	lf = 0ah
string		db	255, 0, 255 dup (?)
errmsg		db	'error: illegal symbol'
crlf		db	cr,lf,'$'
negflag		dw	?

msga		db	cr,lf,'a=$'
msgn		db	cr,lf,'n=$'
msgc		db	cr,lf,'c=$'

a		dw	100 dup(?)
n		dw	?
c		dw	?

	.code

IntegerOut	proc
	push	ax
	push	bx
	push	cx
	push	dx
	xor	cx,cx
	mov	bx,10
	cmp	ax,0
	jge	om
	neg	ax
	push	ax
	mov	ah,2
	mov	dl,'-'
	int	21h
	pop	ax
om:	inc	cx
	xor	dx,dx
	div	bx
	push	dx
	or	ax,ax
	jnz	om
om1:	pop	dx
	add	dx,'0'
	mov	ah,2
	int	21h
	loop	om1
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
IntegerOut	endp

IntegerIn	proc
	push	dx
	push	si
	mov	ah,0ah
	lea	dx,string
	int	21h
	xor	ax,ax
	lea	si,string+2
	mov	negflag,ax
	cmp	byte ptr [si],'-'
	jne	im2
	not	negflag
	inc	si	
	jmp	im3
im2:     cmp	byte ptr [si],'+'
	jne	im3
	inc	si
im3:	cmp	byte ptr [si],cr
	je	iex1
	cmp	byte ptr [si],'0'
	jb	ier
	cmp	byte ptr [si],'9'
	ja	ier
	mov	bx,10
	mul	bx
	sub	byte ptr [si],'0'
	add	al,[si]
	adc	ah,0
	inc	si
	jmp	im3
ier:	lea 	dx,errmsg
	mov	ah,9
	int	21h
	jmp	IntegerIn
iex1:	cmp	negflag,0
	je	iex
	neg	ax
iex:	push	ax
	mov	ah,9
	lea	dx,crlf
	int	21h
	pop	ax
	pop	si
	pop	dx
	ret
IntegerIn	endp

start:	mov	ax,@data
	mov	ds,ax

	print	msgn
	call	IntegerIn
	mov	n,ax

	print	msga
	mov	cx,n
	lea	si,a
m1:	push	cx
	push	si
	call	IntegerIn
	pop	si
	pop	cx
	mov	[Si],ax
	add	si,2
	Loop	m1

;-------------------------------------------
	Lea	Si,a	;адрес массива
	Mov	Cx,n	;число элементов
	inc	cx	;если элементов нечетное число, то четных адресов
			;на 1 больше (чтобы после деления на 2 получилось
			;нужное число)
	shr	cx,1	;число четных адресов
	xor	ax,ax	;младшее слово суммы
	xor	dx,dx	;старшее слово суммы
	xor	bx,bx	;число положительных элементов
m2:	cmp	word ptr[Si],0 ;положительное?
	jle	m3	;<=0 идем на следующее число
	add	ax,[si]	;складываем, если положительное
	adc	dx,0	;учитываем перенос
	inc	bx	;считаем количество
m3:	Add	Si,4	;следующий четный адрес через слово
	Loop 	m2	;по всем четным адресам
	idiv	bx	;делим на количество
	mov	c,ax	;сохраним цклую часть среднего арифметического
			;остаток от деления теряется !!!
;-------------------------------------------

	Print	msga		;вывод массива
	mov	Cx,n
	Lea	Si,a

m4:	lodsw			;очередное число
	Call	integerOut	;выводим
	mov	ah,2
	mov	dl,' '		;разделительный пробел
	int	21h
	loop	m4
	
	Print	msgc		;вывод среднего арифмет
	mov	ax,c
	Call	integerOut

exit:	mov	ah,4ch
	int	21h
	end	start


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