; Вариант 5 2 2 ; 5. Отрицательные элементы массива записываются в начале, положительные -- в ; конце ; 2. Конечный массив состоит из элементов исходного, которые больше среднего ; арифметического наибольшего и последнего элементов ; 2. Для обработки исходного массива должна использоваться индексная адресация, ; для формированя конечного -- базовая. ; Сегмент стека. Область памяти, используемая для хранения промежуточных ; значений в вычислениях. STACK SEGMENT PARA STACK 'STACK' DB 100H DUP(?) ; Размер стека -- 0x100 == 256 байт STACK ENDS ; Сегмент данных. Область памяти, в которой содержатся два массива: исходный ; и конечный. DATA SEGMENT PARA PUBLIC 'DATA' ARR1 DW 3,-5,7,21,-3,9,0,11,-14,2 ; Исходные значения ARR2 DW 10 DUP(0) ; Место для конечного массива DATA ENDS ; Сегмент кода. Исполняемая часть содержимого оперативной памяти. CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS: CODE, DS: DATA, SS: STACK START: MOV AX, DATA MOV DS, AX PUSH ARR1[2*10-2] ; Сохраняем последний элемент ; Перестановка элементов исходного массива. ; ; В задании ничего не сказано о порядке элементов внутри группы ; отрицательных и группы положительных чисел, в связи с чем применим ; алгоритм, в результате которого положительные элементы оказываются ; в обратном порядке, а отрицательные перемешаны хаотично. Также ; ничего не сказано про 0: указано лишь разделение на отрицательные ; и положительные. В связи с этим 0 считается положительным числом. ; ; Хранится два указателя: один для обхода массива, другой определяет ; элемент перед началом группы положительных чисел. Когда во время ; обхода встречается положительный элемент, происходит перестановка ; элементов по двум указателям и второй указатель смещается влево на ; одну позицию. Цикл завершается в тот момент, когда оба указателя ; имеют один и тот же адрес. XOR SI, SI ; Очистка указателя на текущее число MOV CX, 10 ; Инициализация счётчика MOV DI, CX ; Инициализация указателя на группу DEC DI ; неотрицательных элементов SHL DI, 1 ; (DI = 2*(число элементов - 1)) TRANSFORM: ; Начало цикла обхода MOV AX, ARR1[SI] ; Считывание текущего элемента CMP AX, 0 ; Сравнение его с 0 JGE SWAP ; Если он меньше, то NOSWAP: ; массив оставляем без изменений, ADD SI, 2 ; переходим к следующему элементу JMP LOOP2_END ; и к следующей итерации SWAP: ; Если больше, то MOV BX, ARR1[DI] ; меняем элемент перед положительными MOV ARR1[DI], AX ; с текущим элементом, используя MOV ARR1[SI], BX ; дополнительно регистр BX, SUB DI, 2 ; после чего сдвигаем границу группы DEC CX ; и уменьшаем счётчик LOOP1_END: ; Конец итерации LOOP TRANSFORM ; и переход к следующей или из цикла ; Поиск наибольшего элемента исходного массива. MOV DX, ARR1[0] ; Максимальным считаем первое число MOV SI, 2 ; Очистка указателя на текущее число MOV CX, 9 ; Инициализация счётчика FIND: ; Начало цикла поиска MOV AX, ARR1[SI] ; Считывание текущего элемента CMP AX, DX ; Сравнение с найденным максимальным JLE LOOP2_END ; элементом, и если больше, NEWMAX: ; то записываем на место найденного MOV DX, AX ; новый наибольший. LOOP2_END: ; Выходим из тела цикла, ADD SI, 2 ; выбирая следующий элемент LOOP FIND ; и переходя к следующей итерации ; Поиск среднего арифметического последнего и наибольшего элементов ; исходного массива. POP AX ; Берём из стека последний элемент ADD DX, AX ; Складываем с максимальным SHR DX, 1 ; и делим результат пополам ; Очищаем конечный массив. XOR SI, SI ; Очистка указателя MOV CX, 9 ; Инициализация счётчика CLEAN: ; Начало цикла очистки MOV ARR2[SI], 2 ; Запись нуля в ячейку памяти ADD SI, 2 ; Инкремент указателя LOOP CLEAN ; Переход к следующей итерации ; Формируем конечный массив. LEA BX, ARR2 ; Определяем адрес конечного массива XOR SI, SI ; Обнуляем указатели на их элементы XOR DI, DI ; для смещения в индексной записи MOV CX, 10 ; Инициализируем счётчик COPY_LOOP: ; Начало цикла копирования MOV BX, ARR1[SI] ; Считываем текущий элемент CMP AX, DX ; Сравниваем с контрольным значением JLE LOOP4_END ; Если текущий элемент больше, COPY: ; то копируем его в конечный массив MOV [BX+DI], AX ; по заданному индексу ADD DI, 2 ; и увеличиваем смещение LOOP4_END: ; Затем, скопировали или нет, ADD SI, 2 ; приращиваем смещение для исходного LOOP COPY_LOOP ; и начинаем следующую итерацию ; Завершение программы. Отправление MS-DOS прерывания выхода из неё. MOV AX, 4C00H INT 21H CODE ENDS END START