Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.10.2009, 15:42   #1
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию сортировка массива

Необходимо отсортировать массив:
Код:
.model small
.code
main: 
	mov ax,@data
	mov ds,ax

;ввод значений
	mov bx,offset arr
	mov cx,5
	xor si,si
	xor ax,ax
i_loop:
	call input
	mov [bx+si],ax
	add si,2
	xor ax,ax
	loop i_loop
;===========================================================
input proc near	;процедура ввода значения
;сохранение регистров

;записать в buff строку
	mov ah,0ah
	mov dx,offset buff ; адрес буфера
	int 21h 
	
;перевести строку
	mov dl,0ah
	mov ah,02
	int 21h 
	
;проверка на ввод корректного значения
	
; обрабатываем содержимое буфера
	mov si,offset buff+2 ;адрес начала строки
	cmp byte ptr[si]," "
	je _prop
	cmp byte ptr [si],"-" ; если первый символ минус
	jnz _poloz	;в противном случае перейти на обработку положительных
	mov di,1  ; устанавливаем флаг
_prop:
	inc si    ; переходим на следующее
	
_poloz:
	xor ax,ax
	mov bx,10  ; основание системы счисления
_perevod:
	mov cl,[si] ; берем символ из буфера
	cmp cl,0dh  ; проверям равен ли символ переводу строки
	jz _endin	;перейти на конец обработки
	
; если символ не последний, то проверяем его на правильность
	cmp cl,30h  ; если введен неверный символ <0
    	jl _err	
    	cmp cl,39h  ; если введен неверный символ >9
    	ja _err

	sub cl,30h ; делаем из символа число 
	mul bx     ; умножаем на 10
	add ax,cx  ; прибавляем к остальным
	inc si     ; переходим на следующее число
	jmp _perevod	; повторяем

; если была ошибка, то выводим сообщение об этом и выходим
_err:
	mov dx, offset error
	mov ah,09
	int 21h
	int 20h

; все символы из буфера обработаны число находится в ax
_endin:
	cmp di,1 ; если установлен флаг, то
	jnz _endp
	neg ax   ; делаем число отрицательным
_endp:
;возвращаем значения регистров
	ret  
input endp


;=====================================================================		
;сортировка		
	mov bx,offset arr
	mov cx,4
	xor si,si	
cyc:
	push cx
	xor si,si	
	mov cx,2
	dec cx	
cyc2:
      mov ax, [bx+si]
      mov dx,[bx+si+2]
      cmp ax,dx
      jle _end_if
      
      mov [bx+si],dx
      mov [bx+si+2],ax
      
_end_if:
      add si,2
      loop cyc2

    	pop cx
      loop cyc	
	

;завершение программы
	mov ax,4c00h
	int 21h
	
.data
arr db 5 dup (?)
error db "Введено не число$"
buff	db 5,6 Dup(?)
.stack 100h
end main
Ошибка при вводе значений, появляется бесконечный цикл, как испарвить?
Единственное, что ограничивает полет мысли программиста-компилятор

Последний раз редактировалось Stilet; 12.10.2009 в 13:30.
Sparky вне форума Ответить с цитированием
Старый 11.10.2009, 15:57   #2
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

1. Сохранять cx перед вызовом input'a и восстанавливать после.
2. Убрать input из центра программы куда-нибудь или обходить его.
3. Все-таки пользоваться отладчиками.
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4
Goodwin98 вне форума Ответить с цитированием
Старый 12.10.2009, 12:29   #3
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

Прблема в том что ттеперь если в массиве есть отрицателный элемент, то при выводе происходит исключение. отладчик показал что это инструкция div bx

Код:
.model tiny
.code
org 100h
main: 
;============================================================================
;ввод
	mov cx,5
	xor si,si
	xor di,di
;\11	mov i,si
input:
	xor ax,ax
	xor dx,dx
	xor bx,bx
	push cx
	;mov ax,word ptr arr[si]
	push si
	;mov si,i
	mov ah,0ah
	mov dx,offset buff ; адрес буфера
	int 21h 
	
;перевести строку
	mov dl,0ah
	mov ah,02;
	int 21h 
	
; обрабатываем содержимое буфера
	mov si,offset buff+2 ;адрес начала строки
	cmp byte ptr[si]," "
	je _prop
	cmp byte ptr [si],"-" ; если первый символ минус
	jnz _poloz	;в противном случае перейти на обработку положительных
	mov di,1  ; устанавливаем флаг
_prop:
	inc si    ; переходим на следующее
	
_poloz:
	xor ax,ax
	mov bx,10  ; основание системы счисления
_perevod:
	mov cl,[si] ; берем символ из буфера
	cmp cl,0dh  ; проверям равен ли символ переводу строки
	jz _endin	;перейти на конец обработки
	
; если символ не последний, то проверяем его на правильность
	cmp cl,30h  ; если введен неверный символ <0
    	jl _err	
    	cmp cl,39h  ; если введен неверный символ >9
    	ja _err

	sub cl,30h ; делаем из символа число 
	mul bx     ; умножаем на 10
	add ax,cx  ; прибавляем к остальным
	inc si     ; переходим на следующее число
	jmp _perevod	; повторяем

; если была ошибка, то выводим сообщение об этом и выходим
_err:
	mov dx, offset error
	mov ah,09
	int 21h
	int 20h

; все символы из буфера обработаны число находится в ax
_endin:
	cmp di,1 ; если установлен флаг, то
	jnz _endp
	neg ax   ; делаем число отрицательным
	
_endp:
;возвращаем значения регистров
	;mov i,si
	pop si
	pop	cx
	mov  word ptr arr[si],ax
	add si,2
	loop input
;============================================================================
;сортировка
	lea bx,arr
	xor si,si
      mov cx,4
cyc1:
      push cx
	xor si,si
      mov di,2
      mov cx,5
      dec cx
cyc2:
	mov ax,word ptr [bx+si]
     	mov dx,word ptr [bx+di]
      cmp ax,dx
      jle _end_if
      mov word ptr  [bx+si],dx
           mov word ptr  [bx+di],ax
_end_if:
      add si,2
      add di,2
      loop cyc2

      pop cx
      loop cyc1
;==================================================================
;вывод
	mov cx,5
     	xor si,si
     
output:
	push cx
      mov ax, word ptr arr [si] 
oi1:    
                                            
      	xor     cx, cx
      	mov     bx, 10

oi2:        
	cwd   
	      ;xor dx,dx                                                             
      	div     bx    ;Делим число на десять. В остатке получается последняя цифра. Сразу выводить её нельзя, поэтому сохраним её в стэке.
      	push    dx
      	inc     cx
; А с частным повторяем то же самое, отделяя от него очередную
; цифру справа, пока не останется ноль, что значит, что дальше
; слева только нули.
    	test    ax, ax  
     	jnz     oi2

; Теперь приступим к выводу.
    	mov     ah, 02h
oi3:   
    	pop     dx
    ;Извлекаем очередную цифру, переводим её в символ и выводим.
     	add     dl, 30h
     	int     21h
; Повторим ровно столько раз, сколько цифр насчитали.
     	loop    oi3 
     	  
     	add si,2    
     	pop cx
	mov dx," "
	mov ah,02h
	int 21h
	
	loop output
	ret
arr dw 5 dup (?)
error db "Введено не число$"
buff	db 5,6 dup(?)
end main
Единственное, что ограничивает полет мысли программиста-компилятор

Последний раз редактировалось Stilet; 12.10.2009 в 13:32.
Sparky вне форума Ответить с цитированием
Старый 12.10.2009, 16:21   #4
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

В выводе убрать cwd и вернуть xor dx,dx
При выводе учитывать знак(я вроде давал пример как)
xor di,di должен быть внутри процедуры input, а не до нее.
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4
Goodwin98 вне форума Ответить с цитированием
Старый 23.10.2009, 17:57   #5
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

вот что у меня получилось, но все равно при работе с отрицательными числа не корректный вывод
Код:
.model tiny
.code
org 100h
main: 
;============================================================================
;ввод
	mov cx,5
	xor si,si
	;xor di,di
input:
	xor ax,ax
	xor dx,dx
	xor bx,bx
	xor di,di
	push cx
	push si
	mov ah,0ah
	mov dx,offset buff ; адрес буфера
	int 21h 
	
;перевести строку
	mov dl,0ah
	mov ah,02;
	int 21h 
	
; обрабатываем содержимое буфера
	mov si,offset buff+2 ;адрес начала строки
	cmp byte ptr[si]," "
	je _prop
	cmp byte ptr [si],"-" ; если первый символ минус
	jnz _poloz	;в противном случае перейти на обработку положительных
	mov di,1  ; устанавливаем флаг
	;neg ax
_prop:
	inc si    ; переходим на следующее
	
_poloz:
	xor ax,ax
	mov bx,10  ; основание системы счисления
_perevod:
	mov cl,[si] ; берем символ из буфера
	cmp cl,0dh  ; проверям равен ли символ переводу строки
	jz _endin	;перейти на конец обработки
	
; если символ не последний, то проверяем его на правильность
	cmp cl,30h  ; если введен неверный символ <0
    	jl _err	
    	cmp cl,39h  ; если введен неверный символ >9
    	ja _err

	sub cl,30h ; делаем из символа число 
	mul bx     ; умножаем на 10
	add ax,cx  ; прибавляем к остальным
	inc si     ; переходим на следующее число
	jmp _perevod	; повторяем

; если была ошибка, то выводим сообщение об этом и выходим
_err:
	mov dx, offset error
	mov ah,09
	int 21h
	int 20h

; все символы из буфера обработаны число находится в ax
_endin:
	cmp di,1 ; если установлен флаг, то
	jnz _endp
	neg ax   ; делаем число отрицательным
	
_endp:
;возвращаем значения регистров
	;mov i,si
	pop si
	pop	cx
	mov  word ptr arr[si],ax
	add si,2
	loop input
;============================================================================
;сортировка
	lea bx,arr
	xor si,si
      mov cx,4
cyc1:
      push cx
	xor si,si
      mov di,2
      mov cx,5
      dec cx
cyc2:
	mov ax,word ptr [bx+si]
     	mov dx,word ptr [bx+di]
      cmp ax,dx
      jle _end_if
      mov word ptr  [bx+si],dx
      mov word ptr  [bx+di],ax
_end_if:
      add si,2
      add di,2
      loop cyc2

      pop cx
      loop cyc1
;==================================================================
	mov cx,5
     	xor si,si
     	xor ax,ax
     	xor dx,dx
output:
	push cx
	mov ax, word ptr arr [si]   
;; Проверяем число на знак.
        test    ax, ax
        jns     @oi1

;; Если оно отрицательное, выведем минус и оставим его модуль.
        mov     ah, 02h
        mov     dl, '-'
        int     21h
        pop     ax
        push    ax
        ;neg ax
        
;; Количество цифр будем держать в CX.
@oi1:  
        xor     cx, cx
        mov     bx, 10
@oi2:   
       ;cwd
       xor dx,dx
       div bx
; Делим число на десять. В остатке получается последняя цифра.
; Сразу выводить её нельзя, поэтому сохраним её в стэке.
        push    dx
        inc     cx
; А с частным повторяем то же самое, отделяя от него очередную
; цифру справа, пока не останется ноль, что значит, что дальше
; слева только нули.
        test    ax, ax
        jnz     @oi2
; Теперь приступим к выводу.
        mov     ah, 02h
@oi3:   pop     dx
; Извлекаем очередную цифру, переводим её в символ и выводим.
        add     dl, 30h
        int     21h
; Повторим ровно столько раз, сколько цифр насчитали.
        loop    @oi3
		
     	add si,2    
     	pop cx
	mov dx," "
	mov ah,02h
	int 21h
	loop output	
        
	ret
arr dw 5 dup (?)
error db "Введено не число$"
buff	db 5,6 dup(?)
end main
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 24.10.2009, 05:14   #6
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

Наверно надо расскоментировать обратно все neg ax.
И еще после
Код:
output:
	push cx
	mov ax, word ptr arr [si]
добавте push ax. А после где-нибудь соответственно pop ax.
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4

Последний раз редактировалось Goodwin98; 24.10.2009 в 05:30.
Goodwin98 вне форума Ответить с цитированием
Старый 26.10.2009, 11:57   #7
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

все проблема решена. если кому-то понадобится пишите
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сортировка массива ManU Помощь студентам 1 21.09.2008 10:41
Сортировка массива Dagmaria Общие вопросы C/C++ 5 05.07.2008 00:23
Сортировка массива Kraven Общие вопросы Delphi 3 25.06.2008 18:22
Сортировка массива...? Roberto Помощь студентам 2 11.04.2008 13:32
Сортировка массива RIO Помощь студентам 1 05.04.2008 17:39