 |
Ассемблер в примерах - Поиск среднего арифметического
- Вопрос:
- Найти среднее арифметическое положительных элементов, с четными номерами.
дальше прилагается код программы который надо изменить.
.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
|  |