CONST
n = 15;
m1 = 4; {Беру маленькое число, чтобы была высокая вероятность появления нулей}
m2 = m1 div 2;
VAR
Z: array[1..n] of Integer;
last_zerou, i: Integer;
summ1, summ2: Integer;
BEGIN
WriteLn('Заполнение массива');
last_zerou:=0;
Randomize;
for i := 1 to n do
{Write('Введите элемент ',i,: ;); ReadLn(Z[i];}
Z[i] := random(m1) - m2; {(i - m2)*(i - m2) - m1;}
for i:=1 to n do Write(Z[i]:4); WriteLn;
WriteLn('Поиск последнего нулевого значения');
asm
lea si, Z
cld
mov cx, n
@@1:
mov ax, [si] {эти две строчки делаю то же, что и LODSW}
add si, 2
or ax, ax {Число не изменяется, только устанавливаются флаги
нас интересуют два
ZF - флаг нуля, SF - флаг знака}
jnz @@2 {переход, если не ноль}
mov ax, n
sub ax, cx
inc ax
mov last_zerou, ax
@@2:
LOOP @@1
end;
if last_zerou = 0 then
WriteLn('В массиве нет нулевых значений')
else
begin
WriteLn('Индекс последнего нулевого элемента: ',last_zerou);
asm
xor ax, ax {побитовая инструкция:
сравниваются биты приемника (первый операнд)
и источника (второй операнд).
Если биты равны, то соответствующий
бит приемника устанавливаются в ноль.
Самый быстрый способ обнулить регистр}
mov summ1, ax
lea si, Z
mov dx, last_zerou
mov cx, 1
@@1:
mov ax, [si]
add si, 2
test ax, 1 {Логическое сравнение. Вычисляется побитовое "И"
Результат нигде не сохраняется, только устанавливаются
флаги
В данном случае источник = 1. Установлен только
нулевой бит (младший, счет с нуля)
Так что результат не равен нулю только в том
случае, когда в применике установлен этот
младший бит. Поскольку "цена" всех остальных бит
четная, то число нечетное, если установлен младший бит}
jnz @@2 {Переход, если не установлен нулевой бит - четное}
add summ1, ax
@@2:
inc cx
cmp cx, dx
jb @@1
@@3:
end;
WriteLn('Сумма четных "до": ', summ1);
asm
mov bx, last_zerou
cmp bx, 1
jbe @@2 {один элемент "до" - он и есть среднее}
dec bx {сам последний в счет не входит}
mov ax, summ1
xor dx, dx
or ax, ax
jns @@1
mov dx, 0FFFFh {Выполняем знаковое деление DX:AX на BX.
если число отрицательное, то DX = FFFF
Легче всего убедиться в этом, если пропустите
эту операцию, а сумма будет отрицательной}
@@1:
idiv bx
mov summ1, ax
@@2:
end;
WriteLn('Среднее арифметическое элементов "до": ', summ1);
asm
xor ax, ax
mov summ2, ax
lea si, Z
mov ax, last_zerou
shl ax, 1 {*2 т.к. каждый элемент занимает 2 байта}
add si, ax {теперь DS:SI указывает на последний нуль}
mov dx, last_zerou
mov cx, n
cld
@@1:
cmp dx, cx
jae @@3
mov ax, [si]
add si, 2
test ax, 1
jz @@2
add summ2, ax
@@2:
inc dx
jmp @@1
@@3:
end;
WriteLn('Сумма нечетных элементов "после": ', summ2);
end;
END.
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.