Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


Благодарю за ответ DillerInc

Цитата:
Для начала одна неувязочка(то ли я туплю с утра,то ли...):

ArraySize DW 20 DUP(0)

...это ж массив,состоящий из двадцати нулевых слов(WORD),а ты его используешь как двухбайтовую величину,характеризующую общий размер массива...
В новом варианте кода понятие размерность и память под эту размерность организовано как ArraySize и Array. И нет необходимости в коде программы использовать mov cx, 20h ведь можно написать следующие mov cx, ArraySize.
Это по аналоги с С где (при работе с массивами) один раз пишем const int n=10 а далее везде по коду ссылаемся на n.
Захотели поменять размерность массива - так поменяли её сразу в шапке, а не по всему коду.

Я немного структурировал код

Код: Выделить весь код
;DS:DI – адрес массива должен быть здесь

TITLE The bubble way of sorting the array	

SSEG SEGMENT PARA STACK 'STACK'			
	DB 16 DUP(0)
SSEG ENDS

DSEG SEGMENT PARA PUBLIC 'DATA'			
Msg1	DB 0dh,' Массив не упорядоченных данных - ','$'
Msg2	DB 0ah,0dh,' Массив упорядоченных данных - ','$'
ArraySize DW 10  				;задаём размерность массива
Array DB 2,9,3,8,4,7,6,5,0,1		;заполняем массив
i DB 0
DSEG ENDS					

CSEG SEGMENT PARA PUBLIC 'CODE'
	ASSUME CS:CSEG,DS:DSEG,SS:SSEG

PROC MAIN NEAR			;главная процедура программы (по аналоги с С)
		mov ax,DSEG	
		mov ds,ax	
		mov	ax,0

		mov	cx,ArraySize	
		mov	si,0
		mov	ah,09h
		lea	dx,Msg1
		int	21h
		call SHOW		

		call BUBBLE_SORT		;вызываем процедуру сортирования

		mov	cx,ArraySize	
		mov	si,0
		mov	ah,09h
		lea	dx,Msg2
		int	21h
		call SHOW

exit:
		mov	ax,4c00h	;стандартное завершение программы
		int	21h
MAIN ENDP

BUBBLE_SORT PROC NEAR		
			
		cld			
		lea si,Array	;source
		lea di,Array	;destany
		mov cx,ArraySize	
		rep movsw
				
		mov dx,ArraySize
		cmp dx,1		
		jbe sort_exit	
		dec dx			
sb_loop1:
		mov cx,dx	
		xor bx,bx		
		mov si,di		
sb_loop2:
		lodsw		
		cmp ax,word ptr [si]
		jbe no_swap		
		xchg ax,word ptr [si]	
		mov word ptr [si-2],ax
		inc bx			
no_swap:
		loop sb_loop2
		cmp bx,0		
		jne sb_loop1	
sort_exit:			
		ret			
BUBBLE_SORT ENDP	

PROC SHOW NEAR				;процедура вывода на экран массива до и после сортировки
		mov	ah,02h	
		mov	dl,Array[si]
		add	dl,30h	
		int	21h
		inc	si
		loop show
		ret
SHOW ENDP			

CSEG ENDS					
	END MAIN
Сразу хочу отметить, что работает вывод на экран, однако нет сортировки ... И всё зависит как раз от подсказанного участка кода
Цитата DillerInc (11:45, 28-11-2006):
Код: Выделить весь код
     cld
      lea    si, source       ; источник = какой-нибудь адрес в памяти
      lea    di, ArraySize  ; приёмник
      mov  cx, 20h           ; размер массива
rep movsw                   ; пересылаем из источника в приёмник двадцать слов
А всё таки смысл в этих строчка кода? По сути, копируем из одного источника в другой? Или здесь более сложный подход - они разрешают корректную работу lodsw. Так я нашёл код (Только заполнения и вывода на экран элементов массива) где обходятся без данного оператора и все последующие элементы читают посредством INC SI + Array[si]
Код: Выделить весь код
TITLE Initialization massive

SSEG SEGMENT PARA STACK 'STACK'			;Сегмент стека. SSEG - это имя
	DB 32 DUP(0)
SSEG ENDS

DSEG SEGMENT PARA PUBLIC 'DATA'			;Сегмент данных
Msg1	DB 0dh,' Массив не упорядоченных данных - ','$'
Msg2	DB 0ah,0dh,' Массив упорядоченных данных - ','$'
ArraySize DW 10  				;Размер под массив
Array DB 9,2,3,8,4,7,6,5,0,1			;Память под массив элементов
i DB 0
DSEG ENDS					;DB/DW - Define Bytes/Words
CSEG SEGMENT PARA PUBLIC 'CODE'
	ASSUME CS:CSEG,DS:DSEG,SS:SSEG

MASSIVE PROC NEAR				;Procedure Definition

main:
	mov	ax,DSEG
	mov	ds,ax
	
;вывод на экран получившегося массива
         
	mov	cx,ArraySize	;значение счетчика цикла в cx
	mov	si,0
	mov	ah,09h
	lea	dx,Msg1
	int	21h
	call	show
           
	
	mov	cx,ArraySize	;значение счетчика цикла в cx
	mov	si,0
	mov	ah,09h
	lea	dx,Msg2
	int	21h
	call	show

exit:
	mov	ax,4c00h	;стандартный выход
	int	21h

MASSIVE ENDP				;Конец программы

PROC show	NEAR
	mov	ah,02h	;функция вывода значения из al на экран
	mov	dl,Array[si]
	add	dl,30h	;преобразование числа в символ
	int	21h
	inc	si
	loop	show
	ret
show ENDP

CSEG ENDS				;Конец сегмента
	END MASSIVE ;Конец файла
Однако предполагаю, что в случаи с сортированием связка INC SI + Array[si] утруднить процесс кодирования, что не совсем хорошо.

Всё же, что за
Цитата:
source ; источник = какой-нибудь адрес в памяти
нужно указывать?

P.S
В приведённом примере в указанном участке кода используется
Код: Выделить весь код
           lea si,Array	;source  
           lea di,Array	;destany
Естественно, что в процессе выполнения, выведенные на экран массивы, будут одинаковыми
Но если написать следующие
Код: Выделить весь код
           lea si,Array	;source  
           lea di,buff	         ;destany
,
а в шапке данных указать
Код: Выделить весь код
DSEG SEGMENT PARA PUBLIC 'DATA'			
.....
.....
buff DW 10 DUP(?)
.....
.....
DSEG ENDS
то результат работы программы будет следующим
Цитата proga.ехе:
Массив не упорядоченных данных- 2938476501
Массив не упорядоченных данных - ш001654738
ш - это не опечатка, это программа взяла из памяти

Отправлено: 04:12, 06-12-2006 | #24