Здравствуйте, nelly.
Вот, чуть опоздал, если можно так сказать
В приложении код программы (и еще положил исходник в ДОСовской кодировке сюда:
https://rfpro.ru/upload/865)
Снабдил кое-какими комментариями, но если что не понятно будет - спрашивайте
Требуемая подпрограмма сортировки
sort, но до нее вызывается подпрограмма
select, которая переносит на новое место элементы, удовлетворяющие условию
Обратите внимание, как определяется размер массива с помощью
equ, Вы можете свободно прибавлять и удалять элементы - все заново пересчитается. Только не делайте массив пустым!! Кажется, я это недостаточно хорошо проверил
Приложение:
.model small
LOCALS @@ ; метки, начинающиеся с @@ считаются локальными - можно повторять
.stack 100h
.data
ar dw 1234, 6783, 2333, 7921, 10, 3, 2, 1
ar_size equ ($ - ar)/2 ; там "автоматически" определим размерность массива
a_mask dw 101010010000b ; обычно счет с нуля - поэтому маска такая - самый правый ноль = 0-й (самый младшиий) бит
Source db 'Исходный массив:',13,10,'$'
new_Source db 13,10,'Новый массив до сортировки: ',13,10,'$'
sorted db 13,10,'Новый массив после сортировки:',13,10,'$'
InNew db 13,10,'Число элементов, удовлетворяющих условию: $'
PressKey db 13,10,'Нажмите любую клавишу ...$'
new_array dw ar_size dup (?) ; сюда запишем удовлетворяющие
new_array_count dw 0 ; число элементов в новом массиве
.code
start:
mov ax, @data
mov ds, ax
mov es, ax
mov ax, 3
int 10h
lea dx, Source
mov ah, 9
int 21h
cld ; буду использовать строковые инструкции
lea si, ar
mov cx, ar_size
@@1:
lodsw
CALL AX_dec
LOOP @@1
lea si, ar
lea di, new_array
mov cx, ar_size
mov bx, a_mask
CALL select
lea dx, InNew
mov ah, 9
int 21h
mov ax, cx
CALL AX_dec
mov new_array_count, cx
lea dx, new_Source
mov ah, 9
int 21h
lea si, new_array
; CX уже установлен
@@2:
lodsw
CALL AX_dec
LOOP @@2
mov cx, new_array_count
lea si, new_array
CALL sort
lea dx, sorted
mov ah, 9
int 21h
lea si, new_array
mov cx, new_array_count
@@4:
lodsw
CALL AX_dec
LOOP @@4
lea dx, PressKey
mov ah,9
int 21h
xor ax, ax
int 16h
mov ax, 4C00h
int 21h
; процедура отбора в новый массив элементов
; ПРИ ВХОДЕ:
; SI - указывает на исходный массив
; DI - указывает на массив - приемник
; CX - число элементов в исходном
; BX - маска для отбора
; ПРИ ВЫХОДЕ:
; CX - число элементов в новом массиве
select proc
push ax dx
xor dx, dx ; счетчик записанных
@@1:
lodsw
test ax, bx
jnz @@2 ; установлен (=1) какой-то из заданных бит
stosw ; перемещаем
inc dx ; счетчик
@@2:
LOOP @@1
mov cx, dx ; обещал в СХ возвратить число
pop dx ax
ret
select endp
; процедура сортировки
; ПРИ ВХОДЕ:
; SI - адрес массива для сортировки
; CX - число элементов в нем
sort proc
cmp cx, 2
jl @@_exit ; переход, если СХ < 2
; будем использовать такой алогритм:
; сравниваем один элемент по адресу SI с остальными элементами, которые размещены по адресу BX
; при этом DI будет указывать на наименьший, а DX - его значение
; по окончании сравнения, если SI не равно DI, то меняем местами
; затем увеличиваем SI
dec CX ; действительно, если 2 элемента, то нужно будет только 1 сравнение
push ax bx dx di si
sub si, 2
@@1: ; внешний цикл
add si, 2 ; следующий элемент
mov dx, [si] ; считаем его минимальным - запоминаем значение
mov di, si ; запоминаем адрес
mov bx, si ;
push cx
; внутренний цикл
; dec cx ; на один раз меньше
jcxz @@1
@@2:
add bx, 2
mov ax, [bx]
cmp dx, ax
jb @@3
mov dx, ax
mov di, bx
@@3:
LOOP @@2
cmp di, si
je @@4
mov ax, [si]
mov bx, [di]
mov [si], bx
mov [di], ax
@@4:
pop cx
LOOP @@1
pop si di dx bx ax
@@_exit:
ret
sort endp
AX_dec proc ; вывод содержимого AX (без знака)
push ax bx cx dx
mov bx, 10
xor cx, cx
@@1:
xor dx ,dx
div bx
push dx ; запоминаем остаток от деления
inc cx ; увеличиваем значение счетчика запомненных
or ax, ax
jnz @@1
@@out:
pop ax
add al, '0'
int 29h ; это прерывание умеет делать только одно - выводить содержимое AL на текстовый экран
LOOP @@out
; и два пробела для разделения чисел
mov al, ' '
int 29h
int 29h
pop dx cx bx ax
ret
AX_dec endp
end start