Удалить элементы массива, имеющие одинаковые значения - Assembler
Формулировка задачи:
Помогите дописать программу, я составил примерно, но плохо в этом всем понимаю.
Удалить элементы массива А(I) имеющие одинаковые значения. I=1,2,..,10, Определить количество оставшихся элементов.
masm
model small
.stack 256
.data
len equ 10
n db 1,2,3,4,5,6,7,8,9,10
.code
start:
mov ax, @data
mov ds, ax
mov count, 10
xor si, di
jcxz exit
cikle1:
xor ax, ax
cmp n[si], n[di]
je
jmp m
cikle2:
inc si
cmp si, di
jne cikle1
jmp exit
m:
mov di, si
perem:
mov bh, n[di+1]
mov n[di], bh
inc di
mov cx, di
inc cl
cmp cl, count
jne perem
dec count
dec si
mov dl, count
mov di, dx
mov n[di], 0
jmp cikle2
exit:
mov ax, 4c00h
int 21h
end startРешение задачи: «Удалить элементы массива, имеющие одинаковые значения»
textual
Листинг программы
.286 .model tiny .code start: ; ищем повторяющиеся элементы и заменяем их на 0FFh mov cx,lenth+1 mov bx,offset array a2: push cx mov al,[bx] cmp al,0FFh je a1 mov di,bx inc di a0: repne scasb jcxz a1 mov byte ptr [edi-1],0FFh loop a0 a1: inc bx pop cx loop a2 ; ищем элемены отличающиеся от 0FFh и сдвигаем их в начало массива ; таким образом происходит удаление из массива повторяющихся элементов mov al,0FFh a5: xor bx,bx mov cx,lenth mov di,offset array a4: repne scasb jcxz a3 cmp al,[di] je a4 xchg al,[di] xchg al,[di-1] mov bl,1 jmp a4 a3: cmp bx,1 jz a5 ; ищем первый элемент с кодом 0FFh, отнимаем от его адреса адрес начала ;массива, таким образом мы определяем количество оставшихся элементов. mov cx,lenth mov di,offset array mov si,di repne scasb sub di,si dec di ret array db 1,2,1,1,4,2,7,4,1,10 lenth = $ - array end start;конец программы
Объяснение кода листинга программы
- .286 - указание на модель процессора
- .model tiny - указание на модель сегментации
- .code - начало кода
- start: - метка начала функции
- mov cx,lenth+1 - инициализация счётчика циклов
- mov bx,offset array - инициализация базового регистра
- a2: push cx - сохранение счётчика в стеке
- mov al,[bx] - получение значения элемента массива
- cmp al,0FFh - сравнение значения с 0FFh
- je a1 - если значение равно 0FFh, то переход на метку a1
- mov di,bx - запоминание адреса элемента
- inc di - увеличение значения регистра di
- a0: repne scasb - поиск повторяющихся элементов
- jcxz a1 - если счётчик равен нулю, то переход на метку a1
- mov byte ptr [edi-1],0FFh - замена повторяющегося элемента на 0FFh
- loop a0 - повторение шагов с 13 по 15
- a1: inc bx - увеличение значения регистра bx
- pop cx - восстановление значения счётчика из стека
- loop a2 - повторение шагов с 5 по 18
- mov al,0FFh - инициализация значения для поиска элементов, отличающихся от 0FFh
- a5: xor bx,bx - инициализация регистра bx
- mov cx,lenth - инициализация счётчика циклов
- mov di,offset array - инициализация базового регистра
- a4: repne scasb - поиск элементов, отличающихся от 0FFh
- jcxz a3 - если счётчик равен нулю, то переход на метку a3
- cmp al,[di] - сравнение значения с 0FFh
- je a4 - если значение равно 0FFh, то переход на метку a4
- xchg al,[di] - обмен значениями с элементом массива
- xchg al,[di-1] - обмен значениями с предыдущим элементом массива
- mov bl,1 - инициализация регистра bl
- jmp a4 - повторение шагов с 24 по 29
- a3: cmp bx,1 - проверка счётчика элементов, отличающихся от 0FFh
- jz a5 - если счётчик равен нулю, то переход на метку a5
- mov cx,lenth - инициализация счётчика циклов
- mov di,offset array - инициализация Базового регистра
- mov si,di - запоминание адреса начала массива
- repne scasb - поиск первого элемента с кодом 0FFh
- sub di,si - вычисление разницы между адресами
- dec di - уменьшение значения регистра di
- ret - завершение программы
- array db 1,2,1,1,4,2,7,4,1,10 - определение массива
- lenth = $ - array - вычисление длины массива
- end start;конец программы - завершение программы