Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Сортировки массива по убыванию модулей значений

Вопрос:
нужна программа для сортировки массива по убыванию модулей значений. Параметры в процедуре передавать через стек.

Ответ:
	.model	tiny,STDCALL
	.data
array	dw	1, 4,7,-2,10,24,-100,2,101
len	equ	($-array)/2

	.code
	.startup
	lea	ax,array
	mov	cx,len
	call	sort,ax,cx

	.exit	0

;сортировка строки методом "пузырька" по убыванию, 
;массив ar, длина cnt
sort	proc	ar:word, cnt:word
uses	si,di,cx,bx		;сохраним используемые регистры в стеке
	mov	bx,ar		;адрес массива
	xor	si,si		;индекс в массиве
	mov	cx,cnt		;длина масива
	jcxz	sort_ret	;проверим на пустой массив
	dec	cx		;будем проверять до предпоследнего включительно
	jcxz	sort_ret	;проверим, что больше одного элемента
loop1:				;цикл по (первому)элементу, который сравнивается
	push	cx		;сохраним количество
	mov	ax,[bx+si]	;берем первое значение и сравниваем со всеми последующими
	lea	di,[si+2]	;смещение, с чем сравниваем
				;сравниваем cx раз (от последующего до последнего)
loop2:
	call	cmpmod,[bx+di]	;сравним ax и слово по адресу [bx+di]
	jge	next		;на следующий, если ax=[bx+si]>=[bx+di]
	xchg	ax,[bx+di]	;меняем местами arr1[si] и arr1[di]
	mov	[bx+si],ax	;причем в ax будет новый первый(максимальный)элемент
next:
	lea	di,[di+2]	;на следующий элемент
	loop	loop2		;на внутренний цикл
	
	pop	cx		;восстановим счетчик цикла по первым элементам
	lea	si,[si+2]	;на следующий первый элемент
	loop	loop1		;на внешний цикл
sort_ret:
	ret
sort	endp

;сравнение модуля числа из регистра ax и аргумента arg
;результат возвращается во флагах
;Важно, чтобы не использовалась модель передачи параметров C,
;в которой параметры убираются из стека командой add sp,<число>
;которая, в свою очередь, портит флаги.
;Или возвращать результат в виде числа -1,0,1
cmpmod	proc	arg:word
uses	ax,dx			;сохраним регистры
	test	ax,ax		;проверим на знак
	jns	test_second	;положительное - обходим
	neg	ax		;меняем знак
test_second:
	mov	dx,arg		;вторая величина
	test	dx,dx		;проверим на знак
	jns	compare_mod	;положительное - обходим
	neg	dx		;меняем знак
compare_mod:
	cmp	ax,dx		;сравниваем, результат во флагах
	ret
cmpmod	endp

	end


   Вперёд
   Содержание